oag_fastapi_server/emitters/
models.rs1use minijinja::{Environment, context};
2use oag_core::ir::{IrObjectSchema, IrSchema, IrSpec};
3
4use crate::type_mapper::{ir_type_to_python, ir_type_to_python_field};
5
6pub fn emit_models(ir: &IrSpec) -> String {
8 let mut env = Environment::new();
9 env.add_template("models.py.j2", include_str!("../../templates/models.py.j2"))
10 .expect("template should be valid");
11 let tmpl = env.get_template("models.py.j2").unwrap();
12
13 let schemas: Vec<_> = ir.schemas.iter().map(schema_to_ctx).collect();
14
15 tmpl.render(context! {
16 schemas => schemas,
17 })
18 .expect("render should succeed")
19}
20
21fn schema_to_ctx(schema: &IrSchema) -> minijinja::Value {
22 match schema {
23 IrSchema::Object(obj) => object_to_ctx(obj),
24 IrSchema::Enum(e) => {
25 let variants: Vec<minijinja::Value> = e
26 .variants
27 .iter()
28 .map(|v| {
29 context! {
30 name => heck::AsUpperCamelCase(v).to_string(),
31 value => v.clone(),
32 }
33 })
34 .collect();
35 context! {
36 kind => "enum",
37 name => e.name.pascal_case.clone(),
38 description => e.description.clone(),
39 variants => variants,
40 }
41 }
42 IrSchema::Alias(a) => {
43 context! {
44 kind => "alias",
45 name => a.name.pascal_case.clone(),
46 description => a.description.clone(),
47 target => ir_type_to_python(&a.target),
48 }
49 }
50 IrSchema::Union(u) => {
51 let variants: Vec<String> = u.variants.iter().map(ir_type_to_python).collect();
52 context! {
53 kind => "union",
54 name => u.name.pascal_case.clone(),
55 description => u.description.clone(),
56 variants => variants,
57 }
58 }
59 }
60}
61
62fn object_to_ctx(obj: &IrObjectSchema) -> minijinja::Value {
63 let fields: Vec<minijinja::Value> = obj
64 .fields
65 .iter()
66 .map(|f| {
67 context! {
68 name => f.name.snake_case.clone(),
69 original_name => f.original_name.clone(),
70 type_str => ir_type_to_python_field(&f.field_type, f.required),
71 required => f.required,
72 description => f.description.clone(),
73 needs_alias => f.name.snake_case != f.original_name,
74 }
75 })
76 .collect();
77
78 let has_additional_properties = obj.additional_properties.is_some();
79
80 context! {
81 kind => "object",
82 name => obj.name.pascal_case.clone(),
83 description => obj.description.clone(),
84 fields => fields,
85 has_additional_properties => has_additional_properties,
86 }
87}