RibirX / Ribir

Non-intrusive GUI framework for Rust

Home Page:https://ribir.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues in the quick start guide

agluszak opened this issue · comments

I've heard about this library from a /r/rust announcement so I decided to go through the quick start guide, but I found some issues in it.

  • here the "@" syntax is mentioned, but it has not been introduced yet. Also there's a link to a non-existent doc called "Creating an application"
  • Formatting is inconsistent. Sometimes there is a space between rdl! and {, sometimes there isn't
  • "rdl! does not care about types, it only does processing at the syntax level, so it is not only widgets that can use it." - this notice is not clear to me. What does it mean that "rdl!" does not care about types? Procedural macros in general are unable to reason about types.
  • "When your expression is a structure literal, rdl! will create an object through the Declare trait, which requires that the type of the object you create must inherit or implement the Declare trait." What does it mean that a type "inherits" a trait?
  • At this point it is not clear to me why Label is created with ::new and not via the Declare trait
  • Idk if it's a problem with the wording, or with the design of rdl, but you say that "$counter.write() expand[s] to counter.write()", however it actually shrinks, because the result is shorter ;)

to be continued...

Thank you for your favor @agluszak , we'll improve the writing later. And here I try to answer some of your confusion.

  1. the rdl! is a macro to achieve the syntax, it just translate the ribir declare syntax to rust syntax, so we say it does not care about types, however if the type not match, it'll compile failed.
  2. there is two kind of value can be recognize under the rdl! macro:
    • structure literal. when rdl! with structure literal, we'll expand to declare a widget by DeclareBuilder, e.g.:
      rdl!{ Counter { cnt: 0 } }
      will be expand to something like
      Counter::declare_builder().cnt(0).widget_build(ctx!())
    • the other expression. when rdl! with other expression, it will declare a widget from the expression's result, e.g.:
    fn build_counter(cnt: u32) -> impl WidgetBuilder {
        fn_widget! { rdl! { Counter {cnt: cnt} } }
    }
    
    rdl!{ let a = 0;  build_counter(a) }
    
    it's just like to declare the expression's result as a widget
    { let a = 0; build_counter(a) }
    
    this will be helpful for you to do some calculate.
  3. the $xxx.write() not only be expand to counter.write() simple, the framework do more work here. the $xxx may probability be pass to move Closure, the framework will auto clone the $xxx before move, so it's different to use like xxx.write(). e.g.:
pub fn test() -> impl WidgetBuilder {
  fn_widget! {
    let cnt = Stateful::new(0);
    @FilledButton {
      // on_tap: {
      //   let cnt = cnt.clone_writer();
      //   move |_| cnt.write() += 1
      // }
      on_tap: move |_| *$cnt.write() += 1,

      // on_tap: {
      //   let cnt = cnt.clone_writer();
      //   move |_| cnt.write() += 2
      // }
      on_double_tap: move |_| *$cnt.write() += 2;
      @{ Label::new("Inc") }
    }
  }
}
commented

@agluszak
Thank you for your feedback. The issues with the broken links have been addressed and the example code has been formatted in #526.

@wjian23 has provided explanations for the other issues. Regarding the Label, there are two key points to consider:

  • Ribir supports the use of any Rust expression, as long as the result meets the type requirement for a declarative node.
  • In the future, we plan to eliminate the Label entirely and directly support String. The syntax @ { Label::new("Increment") } will be replaced by @ { "Increment" }.

Please feel free to reach out if you have any further questions.