Skip to content

Commit

Permalink
feat: Python codegen init
Browse files Browse the repository at this point in the history
  • Loading branch information
kulikthebird committed Nov 6, 2024
1 parent 08d06c4 commit cc10b12
Show file tree
Hide file tree
Showing 12 changed files with 277 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/cw-schema-codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod go;
pub mod python;
pub mod rust;
pub mod typescript;
3 changes: 2 additions & 1 deletion packages/cw-schema-codegen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ where
Language::Typescript => {
cw_schema_codegen::typescript::process_node(output, schema, node)
}
Language::Go | Language::Python => todo!(),
Language::Python => cw_schema_codegen::python::process_node(output, schema, node),
Language::Go => todo!(),
}
})?;

Expand Down
137 changes: 137 additions & 0 deletions packages/cw-schema-codegen/src/python/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use self::template::{
EnumTemplate, EnumVariantTemplate, FieldTemplate, StructTemplate, TypeTemplate,
};
use heck::ToPascalCase;
use std::{borrow::Cow, io};

pub mod template;

fn expand_node_name<'a>(
schema: &'a cw_schema::SchemaV1,
node: &'a cw_schema::Node,
) -> Cow<'a, str> {
match node.value {
cw_schema::NodeType::Array { items } => {
let items = &schema.definitions[items];
format!("{}[]", expand_node_name(schema, items)).into()
}
cw_schema::NodeType::Float => "number".into(),
cw_schema::NodeType::Double => "number".into(),
cw_schema::NodeType::Boolean => "boolean".into(),
cw_schema::NodeType::String => "string".into(),
cw_schema::NodeType::Integer { .. } => "string".into(),
cw_schema::NodeType::Binary => "Uint8Array".into(),
cw_schema::NodeType::Optional { inner } => {
let inner = &schema.definitions[inner];
format!("{} | null", expand_node_name(schema, inner)).into()
}
cw_schema::NodeType::Struct(..) => node.name.as_ref().into(),
cw_schema::NodeType::Tuple { ref items } => {
let items = items
.iter()
.map(|item| expand_node_name(schema, &schema.definitions[*item]))
.collect::<Vec<_>>()
.join(", ");

format!("[{}]", items).into()
}
cw_schema::NodeType::Enum { .. } => node.name.as_ref().into(),

cw_schema::NodeType::Decimal { .. } => "string".into(),
cw_schema::NodeType::Address => "string".into(),
cw_schema::NodeType::Checksum => todo!(),
cw_schema::NodeType::HexBinary => todo!(),
cw_schema::NodeType::Timestamp => todo!(),
cw_schema::NodeType::Unit => Cow::Borrowed("void"),
}
}

fn prepare_docs(desc: Option<&str>) -> Cow<'_, [Cow<'_, str>]> {
desc.map(|desc| desc.lines().map(Into::into).collect())
.unwrap_or(Cow::Borrowed(&[]))
}

pub fn process_node<O>(
output: &mut O,
schema: &cw_schema::SchemaV1,
node: &cw_schema::Node,
) -> io::Result<()>
where
O: io::Write,
{
match node.value {
cw_schema::NodeType::Struct(ref sty) => {
let structt = StructTemplate {
name: node.name.clone(),
docs: prepare_docs(node.description.as_deref()),
ty: match sty {
cw_schema::StructType::Unit => TypeTemplate::Unit,
cw_schema::StructType::Named { ref properties } => TypeTemplate::Named {
fields: properties
.iter()
.map(|(name, prop)| FieldTemplate {
name: Cow::Borrowed(name),
docs: prepare_docs(prop.description.as_deref()),
ty: expand_node_name(schema, &schema.definitions[prop.value]),
})
.collect(),
},
cw_schema::StructType::Tuple { ref items } => TypeTemplate::Tuple(
items
.iter()
.map(|item| expand_node_name(schema, &schema.definitions[*item]))
.collect(),
),
},
};

writeln!(output, "{structt}")?;
}
cw_schema::NodeType::Enum { ref cases, .. } => {
let enumm = EnumTemplate {
name: node.name.clone(),
docs: prepare_docs(node.description.as_deref()),
variants: cases
.iter()
.map(|(name, case)| EnumVariantTemplate {
name: name.clone(),
docs: prepare_docs(case.description.as_deref()),
ty: match case.value {
cw_schema::EnumValue::Unit => TypeTemplate::Unit,
cw_schema::EnumValue::Tuple { ref items } => {
let items = items
.iter()
.map(|item| {
expand_node_name(schema, &schema.definitions[*item])
})
.collect();

TypeTemplate::Tuple(items)
}
cw_schema::EnumValue::Named { ref properties, .. } => {
TypeTemplate::Named {
fields: properties
.iter()
.map(|(name, prop)| FieldTemplate {
name: Cow::Borrowed(name),
docs: prepare_docs(prop.description.as_deref()),
ty: expand_node_name(
schema,
&schema.definitions[prop.value],
),
})
.collect(),
}
}
},
})
.collect(),
};

writeln!(output, "{enumm}")?;
}
_ => (),
}

Ok(())
}
41 changes: 41 additions & 0 deletions packages/cw-schema-codegen/src/python/template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use askama::Template;
use std::borrow::Cow;

#[derive(Clone)]
pub struct EnumVariantTemplate<'a> {
pub name: Cow<'a, str>,
pub docs: Cow<'a, [Cow<'a, str>]>,
pub ty: TypeTemplate<'a>,
}

#[derive(Template)]
#[template(escape = "none", path = "python/enum.tpl.py")]
pub struct EnumTemplate<'a> {
pub name: Cow<'a, str>,
pub docs: Cow<'a, [Cow<'a, str>]>,
pub variants: Cow<'a, [EnumVariantTemplate<'a>]>,
}

#[derive(Clone)]
pub struct FieldTemplate<'a> {
pub name: Cow<'a, str>,
pub docs: Cow<'a, [Cow<'a, str>]>,
pub ty: Cow<'a, str>,
}

#[derive(Clone)]
pub enum TypeTemplate<'a> {
Unit,
Tuple(Cow<'a, [Cow<'a, str>]>),
Named {
fields: Cow<'a, [FieldTemplate<'a>]>,
},
}

#[derive(Template)]
#[template(escape = "none", path = "python/struct.tpl.py")]
pub struct StructTemplate<'a> {
pub name: Cow<'a, str>,
pub docs: Cow<'a, [Cow<'a, str>]>,
pub ty: TypeTemplate<'a>,
}
40 changes: 40 additions & 0 deletions packages/cw-schema-codegen/templates/python/enum.tpl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# This code is @generated by cw-schema-codegen. Do not modify this manually.

/**
{% for doc in docs %}
* {{ doc }}
{% endfor %}
*/

type {{ name }} =
{% for variant in variants %}
|

/**
{% for doc in variant.docs %}
* {{ doc }}
{% endfor %}
*/

{% match variant.ty %}
{% when TypeTemplate::Unit %}
{ "{{ variant.name }}": {} }
{% when TypeTemplate::Tuple with (types) %}
{ "{{ variant.name }}": [{{ types|join(", ") }}] }
{% when TypeTemplate::Named with { fields } %}
{ "{{ variant.name }}": {
{% for field in fields %}
/**
{% for doc in field.docs %}
* {{ doc }}
{% endfor %}
*/

{{ field.name }}: {{ field.ty }};
{% endfor %}
} }
{% endmatch %}
{% endfor %}
;

export { {{ name }} };
30 changes: 30 additions & 0 deletions packages/cw-schema-codegen/templates/python/struct.tpl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This code is @generated by cw-schema-codegen. Do not modify this manually.

/**
{% for doc in docs %}
* {{ doc }}
{% endfor %}
*/

type {{ name }} =
{% match ty %}
{% when TypeTemplate::Unit %}
void
{% when TypeTemplate::Tuple with (types) %}
[{{ types|join(", ") }}]
{% when TypeTemplate::Named with { fields } %}
{
{% for field in fields %}
/**
{% for doc in field.docs %}
* {{ doc }}
{% endfor %}
*/

{{ field.name }}: {{ field.ty }};
{% endfor %}
}
{% endmatch %}
;

export { {{ name }} };
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
source: packages/cw-schema-codegen/tests/rust_tpl.rs
expression: rendered
snapshot_kind: text
---
// This code is @generated by cw-schema-codegen. Do not modify this manually.


#[doc = "Complex enum"]


Expand All @@ -18,9 +22,7 @@ pub enum Complex {
One

(

u64,

u64
)

,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
source: packages/cw-schema-codegen/tests/rust_tpl.rs
expression: rendered
snapshot_kind: text
---
// This code is @generated by cw-schema-codegen. Do not modify this manually.


#[doc = "Empty enum"]


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
source: packages/cw-schema-codegen/tests/rust_tpl.rs
expression: rendered
snapshot_kind: text
---
// This code is @generated by cw-schema-codegen. Do not modify this manually.


#[doc = "Empty struct"]


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
source: packages/cw-schema-codegen/tests/rust_tpl.rs
expression: rendered
snapshot_kind: text
---
// This code is @generated by cw-schema-codegen. Do not modify this manually.


#[doc = "Named struct"]


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
source: packages/cw-schema-codegen/tests/rust_tpl.rs
expression: rendered
snapshot_kind: text
---
// This code is @generated by cw-schema-codegen. Do not modify this manually.


#[doc = "Simple enum"]


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
source: packages/cw-schema-codegen/tests/rust_tpl.rs
expression: rendered
snapshot_kind: text
---
// This code is @generated by cw-schema-codegen. Do not modify this manually.


#[doc = "Tuple struct"]


Expand All @@ -10,9 +14,5 @@ pub struct Tuple


(

u64,

String,

u64, String
);

0 comments on commit cc10b12

Please sign in to comment.