In questa sezione

Questa guida mostra come aggiungere attributi ai tipi Rust generati da lungo, come i derive di serde, e come controllarne le implementazioni di Debug e la documentazione.

Deriva serde

Abilita la feature serde di lungo, che implementa serde per Nat, Int, List e gli altri tipi della facciata, e aggiungi tu stesso la dipendenza da serde:

cargo add lungo --features serde
cargo add serde --features derive

Aggiungi il derive ai tipi di un namespace in build.rs:

fn main() -> lungo_build::Result<()> {
    lungo_build::configure()
        .type_attribute("Geometry", "#[derive(serde::Serialize, serde::Deserialize)]")
        .compile_lean("lean")
}

Il percorso Geometry seleziona ogni tipo del namespace Lean Geometry; . seleziona ogni tipo, e Geometry.Point solo quello. I valori Nat e Int si serializzano come stringhe decimali ({"x": "3", "y": "-4"}) perché sono illimitati.

Aggiungi attributi a struct, enum e campi

struct_attribute ed enum_attribute selezionano solo le struct o solo gli enum, e field_attribute seleziona i campi con i loro nomi Lean: <Structure>.<field> per una structure, <Constructor>.<binder> per gli altri costruttori.

lungo_build::configure()
    .type_attribute("Geometry", "#[derive(serde::Serialize, serde::Deserialize)]")
    .struct_attribute("Geometry.Point", "#[serde(deny_unknown_fields)]")
    .enum_attribute("Geometry.Shape", r#"#[serde(tag = "kind", rename_all = "snake_case")]"#)
    .field_attribute("Geometry.Point.x", r#"#[serde(rename = "col")]"#)
    .field_attribute("Geometry.Shape.segment.start", r#"#[serde(rename = "from")]"#)
    .compile_lean("lean")

lungo mappings elenca il nome Lean di ogni tipo e campo generato. Un percorso che non seleziona nulla fa fallire la build con LNG0107, così un percorso scritto male o non più valido non passa inosservato.

Implementa Debug da te

I tipi generati derivano Debug. Per formattare un tipo a modo tuo, per esempio per tenere un segreto fuori dai log, salta il derive:

lungo_build::configure().skip_debug(["Geometry.Secret"]).compile_lean("lean")

e implementalo accanto al modulo generato:

pub mod geometry {
    lungo::include_lean!("geometry");

    impl std::fmt::Debug for Secret {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.write_str("Secret(<redacted>)")
        }
    }
}

Ometti i commenti di documentazione

I tipi e le funzioni generati portano commenti di documentazione con il loro nome Lean, il tipo e la posizione nel sorgente. disable_comments li omette per i tipi e le funzioni selezionati da un percorso:

lungo_build::configure().disable_comments(["Geometry.Internal"]).compile_lean("lean")

In lungo.toml

Le stesse impostazioni nella tabella [rust] di lungo.toml, per il comando lungo:

project = "lean"

[rust]
type-attributes = [
  { path = "Geometry", attribute = "#[derive(serde::Serialize, serde::Deserialize)]" },
]
field-attributes = [{ path = "Geometry.Point.x", attribute = '#[serde(rename = "col")]' }]
skip-debug = ["Geometry.Secret"]

Le impostazioni sono elencate nel riferimento della configurazione. compiler-tests/shaping in lungo-rs le usa tutte.