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 supposed to become a mapping for fields in an sql database to rust enums and the strings are the actual table and column names in the database.

      And now that you'Re asking I actually have an example implementation (generated by a lua script):

      • https://codeberg.org/unobtanium/unobtanium/src/branch/main/lib-unobtanium/src/database/tables.rs
      • https://codeberg.org/unobtanium/unobtanium/src/branch/main/lib-unobtanium/src/database/fields.rs
      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 how can i get the identifiers for the enum variants of the fields?

        like

        Key,
        MimeParameterId,
        MimetypeId,
        Value,
        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 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