Unverified Commit 58c44b7c authored by Nugine's avatar Nugine
Browse files

codegen: dto

parent 723d2b18
Loading
Loading
Loading
Loading
+106 −94
Original line number Diff line number Diff line
@@ -293,6 +293,62 @@ pub fn codegen(rust_types: &RustTypes, g: &mut Codegen) {
                g.ln(f!("pub type {} = Map<{}, {}>;", ty.name, ty.key_type, ty.value_type));
            }
            rust::Type::StrEnum(ty) => {
                codegen_str_enum(ty, rust_types, g);
            }
            rust::Type::Struct(ty) => {
                codegen_struct(ty, rust_types, g);
            }
            rust::Type::StructEnum(ty) => {
                codegen_struct_enum(ty, rust_types, g);
            }
            rust::Type::Timestamp(ty) => {
                codegen_doc(ty.doc.as_deref(), g);
                g.ln(f!("pub type {} = Timestamp;", ty.name));
            }
        }
        g.lf();
    }
}

fn codegen_struct(ty: &rust::Struct, _rust_types: &RustTypes, g: &mut Codegen) {
    let is_rust_default = |v: &Value| match v {
        Value::Bool(x) => !x,
        Value::Number(x) => x.as_i64() == Some(0),
        Value::String(x) => x.is_empty(),
        _ => unimplemented!("{v:#?}"),
    };

    let can_derive_default = ty.fields.iter().all(|field| {
        let is_option = field.option_type;
        let has_default = match field.default_value {
            Some(ref v) => is_rust_default(v),
            None => false,
        };
        is_option || has_default
    });

    codegen_doc(ty.doc.as_deref(), g);
    if can_derive_default {
        g.ln("#[derive(Debug, Default)]");
    } else {
        g.ln("#[derive(Debug)]");
    }
    // g.ln("#[non_exhaustive]"); // TODO: builder?
    g.ln(f!("pub struct {} {{", ty.name));

    for field in &ty.fields {
        codegen_doc(field.doc.as_deref(), g);
        if field.option_type {
            g.ln(f!("    pub {}: Option<{}>,", field.name, field.type_));
        } else {
            g.ln(f!("    pub {}: {},", field.name, field.type_));
        }
    }

    g.ln("}");
}

fn codegen_str_enum(ty: &rust::StrEnum, _rust_types: &RustTypes, g: &mut Codegen) {
    codegen_doc(ty.doc.as_deref(), g);
    g.ln("#[derive(Debug, Clone, PartialEq, Eq)]");
    g.ln(f!("pub struct {}(Cow<'static, str>);", ty.name));
@@ -342,44 +398,8 @@ pub fn codegen(rust_types: &RustTypes, g: &mut Codegen) {
    g.ln("}");
    g.ln("}");
}
            rust::Type::Struct(ty) => {
                let is_rust_default = |v: &Value| match v {
                    Value::Bool(x) => !x,
                    Value::Number(x) => x.as_i64() == Some(0),
                    Value::String(x) => x.is_empty(),
                    _ => unimplemented!("{v:#?}"),
                };

                let can_derive_default = ty.fields.iter().all(|field| {
                    let is_option = field.option_type;
                    let has_default = match field.default_value {
                        Some(ref v) => is_rust_default(v),
                        None => false,
                    };
                    is_option || has_default
                });

                codegen_doc(ty.doc.as_deref(), g);
                if can_derive_default {
                    g.ln("#[derive(Debug, Default)]");
                } else {
                    g.ln("#[derive(Debug)]");
                }
                // g.ln("#[non_exhaustive]"); // TODO: builder?
                g.ln(f!("pub struct {} {{", ty.name));

                for field in &ty.fields {
                    codegen_doc(field.doc.as_deref(), g);
                    if field.option_type {
                        g.ln(f!("    pub {}: Option<{}>,", field.name, field.type_));
                    } else {
                        g.ln(f!("    pub {}: {},", field.name, field.type_));
                    }
                }

                g.ln("}");
            }
            rust::Type::StructEnum(ty) => {
fn codegen_struct_enum(ty: &rust::StructEnum, _rust_types: &RustTypes, g: &mut Codegen) {
    codegen_doc(ty.doc.as_deref(), g);
    g.ln("#[derive(Debug)]");
    g.ln("#[non_exhaustive]");
@@ -392,11 +412,3 @@ pub fn codegen(rust_types: &RustTypes, g: &mut Codegen) {

    g.ln("}");
}
            rust::Type::Timestamp(ty) => {
                codegen_doc(ty.doc.as_deref(), g);
                g.ln(f!("pub type {} = Timestamp;", ty.name));
            }
        }
        g.lf();
    }
}