Spacc BBS Spacc BBS
    • Categorie
    • Recenti
    • Tag
    • Popolare
    • Mondo
    • Utenti
    • Gruppi
    • Registrati
    • Accedi
    La nuova BBS è in fase Alpha. I post precedenti al 22 luglio 2024 potrebbero non essere trasferibili, ma rimarranno disponibili per la lettura su /old/.

    Rusteceans of the Fediverse, can you help me with a declarative macro problem?

    Pianificato Fissato Bloccato Spostato Uncategorized
    rustlang
    23 Post 2 Autori 50 Visualizzazioni
    Caricamento altri post
    • Da Vecchi a Nuovi
    • Da Nuovi a Vecchi
    • Più Voti
    Rispondi
    • Topic risposta
    Effettua l'accesso per rispondere
    Questa discussione è stata eliminata. Solo gli utenti con diritti di gestione possono vederla.
    • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
      slatian@pleroma.envs.net @steffo@a.junimo.party
      ultima modifica di

      @steffo@a.junimo.party That's the inner enums, so FooBarField and FooBazField in my example above.

      steffo@a.junimo.partyS 2 Risposte Ultima Risposta Rispondi Cita 0
      • steffo@a.junimo.partyS Questo utente è esterno a questo forum
        steffo@a.junimo.party @slatian@pleroma.envs.net
        ultima modifica di

        Questo post è eliminato!
        1 Risposta Ultima Risposta Rispondi Cita 0
        • steffo@a.junimo.partyS Questo utente è esterno a questo forum
          steffo@a.junimo.party @slatian@pleroma.envs.net
          ultima modifica di

          @slatian where is SchemaName used then? is it BaseTable?

          slatian@pleroma.envs.netS 1 Risposta Ultima Risposta Rispondi Cita 0
          • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
            slatian@pleroma.envs.net @steffo@a.junimo.party
            ultima modifica di

            @steffo@a.junimo.party

            I've noticed, that I forgot to link a file, this one is where everything gets tied together:

            https://codeberg.org/unobtanium/unobtanium/src/branch/main/lib-unobtanium/src/database/schemas.rs

            steffo@a.junimo.partyS slatian@pleroma.envs.netS 2 Risposte Ultima Risposta Rispondi Cita 0
            • steffo@a.junimo.partyS Questo utente è esterno a questo forum
              steffo@a.junimo.party @slatian@pleroma.envs.net
              ultima modifica di

              @slatian yeah, that can be done, the only impossible thing is appending Field to identifier names, as that would require a procedural macro (an external one would also work)

              shouldn't be an issue because in one case they're enums names and in the other they're enum variants, and the two can be disambiguated

              slatian@pleroma.envs.netS 1 Risposta Ultima Risposta Rispondi Cita 0
              • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
                slatian@pleroma.envs.net @steffo@a.junimo.party
                ultima modifica di

                @steffo@a.junimo.party In that case I think it would be easier to write the whole thing as a procedural macro?

                steffo@a.junimo.partyS 1 Risposta Ultima Risposta Rispondi Cita 0
                • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                  steffo@a.junimo.party @slatian@pleroma.envs.net
                  ultima modifica di

                  @slatian unsure, give me a few mins and i'm (re)writing the macro_rules like that

                  1 Risposta Ultima Risposta Rispondi Cita 0
                  • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
                    slatian@pleroma.envs.net @slatian@pleroma.envs.net
                    ultima modifica di

                    @steffo@a.junimo.party Sorry, I haven't touched that code in quite a while … And I also didn't expect anyone to dive in this deep :drgn_heart:

                    The Declaration for my example would be:

                    sql_schema!{
                        BaseTable
                        enum MimeParameter = "mime_parameter" {
                             Key = "key",
                             MimeParameterId = "mime_parameter_id",
                             // …
                        }
                        enum Mimetype = "mimetype" {
                             // …
                        }
                        enum Origin = "origin" {
                            // …
                        }
                        // …
                    }
                    
                    steffo@a.junimo.partyS 1 Risposta Ultima Risposta Rispondi Cita 0
                    • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                      steffo@a.junimo.party @slatian@pleroma.envs.net
                      ultima modifica di steffo@a.junimo.party

                      @slatian something like this?

                      pub trait Table {
                      fn sql_safe_table_name(&self) -> &'static str;
                      }

                      pub trait Field {
                      fn sql_safe_field_name(&self) -> &'static str;
                      }

                      macro_rules! sql_schema {
                      {
                      $schema_name:ident,
                      $(
                      enum $table_name:ident = $table_value:literal {
                      $( $field_name:ident = $field_value:literal ),*
                      }
                      )*
                      } => {
                      pub enum $schema_name {
                      $( $table_name ),*
                      }

                      impl Table for $schema_name {
                      fn sql_safe_table_name(&self) -> &'static str {
                      match self {
                      $( $schema_name::$table_name => $table_value ),*
                      }
                      }
                      }

                      $(
                      // it's not possible to concatenate things to identifiers without the use of a proc macro
                      // so we just re-use $table_name
                      pub enum $table_name {
                      $( $field_name ),*
                      }

                      impl Field for $table_name {
                      fn sql_safe_field_name(&self) -> &'static str {
                      match self {
                      $( $table_name::$field_name => $field_value ),*
                      }
                      }
                      }
                      )*
                      }
                      }

                      sql_schema! {
                      BaseTable,
                      enum MimeParameter = "mime_parameter" {
                      Key = "key",
                      MimeParameterId = "mime_parameter_id"
                      }
                      enum Mimetype = "mimetype" {
                      Charset = "charset"
                      // …
                      }
                      }

                      you can use cargo expand to see what it generates

                      slatian@pleroma.envs.netS 1 Risposta Ultima Risposta Rispondi Cita 0
                      • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
                        slatian@pleroma.envs.net @steffo@a.junimo.party
                        ultima modifica di

                        @steffo@a.junimo.party It took a while for me to wrap my Brain around this :drgn_sparkle: <- didn't expect it to be that … simple and especially readable.

                        Given that I can almost 1:1 copy this into criterium (licensed LGPL-3.0-only): May I? If yes, what name do you want in the copyright header?

                        steffo@a.junimo.partyS 1 Risposta Ultima Risposta Rispondi Cita 0
                        • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                          steffo@a.junimo.party @slatian@pleroma.envs.net
                          ultima modifica di

                          @slatian sure! you can add Stefano Pigozzi <me@steffo.eu> to the contributors section of Cargo.toml if you want, but dw, it's just a snippet of code that fit in a fedi post

                          steffo@a.junimo.partyS 1 Risposta Ultima Risposta Rispondi Cita 0
                          • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                            steffo@a.junimo.party @steffo@a.junimo.party
                            ultima modifica di steffo@a.junimo.party

                            @slatian a thing to be aware of, $(),* does not allow trailing commas, so this would work

                                enum Mimetype = "mimetype" {
                            Charset = "charset"
                            }

                            but this would give a weird error

                                enum Mimetype = "mimetype" {
                            Charset = "charset",
                            }
                            slatian@pleroma.envs.netS 1 Risposta Ultima Risposta Rispondi Cita 0
                            • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
                              slatian@pleroma.envs.net @steffo@a.junimo.party
                              ultima modifica di

                              @steffo@a.junimo.party

                              The optional comma could just be eaten by a $(…),* $(,)?

                              Or am I missing something? (I don't write a lot of macros.)

                              steffo@a.junimo.partyS 4 Risposte Ultima Risposta Rispondi Cita 0
                              • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                                steffo@a.junimo.party @slatian@pleroma.envs.net
                                ultima modifica di

                                @slatian yep

                                1 Risposta Ultima Risposta Rispondi Cita 0
                                • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                                  steffo@a.junimo.party @slatian@pleroma.envs.net
                                  ultima modifica di

                                  Questo post è eliminato!
                                  1 Risposta Ultima Risposta Rispondi Cita 0
                                  • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                                    steffo@a.junimo.party @slatian@pleroma.envs.net
                                    ultima modifica di

                                    Questo post è eliminato!
                                    1 Risposta Ultima Risposta Rispondi Cita 0
                                    • steffo@a.junimo.partyS Questo utente è esterno a questo forum
                                      steffo@a.junimo.party @slatian@pleroma.envs.net
                                      ultima modifica di

                                      @slatian wait no i remembered correctly

                                      Each repetition in the transcriber must contain at least one metavariable to decide how many times to expand it.

                                      1 Risposta Ultima Risposta Rispondi Cita 0
                                      • slatian@pleroma.envs.netS Questo utente è esterno a questo forum
                                        slatian@pleroma.envs.net @slatian@pleroma.envs.net
                                        ultima modifica di

                                        This is what I ended up with:

                                        https://codeberg.org/unobtanium/criterium/src/branch/main/src/sql/schema_macro.rs

                                        Huge Thank You goes to @steffo@a.junimo.party :drgn_heart:

                                        1 Risposta Ultima Risposta Rispondi Cita 1 0
                                        • steffo@a.junimo.partyS steffo@a.junimo.party shared this topic on
                                        • Primo post
                                          Ultimo post