Skip to content

Commit

Permalink
feat: Add Python codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
kulikthebird committed Nov 19, 2024
1 parent cc10b12 commit e959fba
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 26 deletions.
1 change: 1 addition & 0 deletions packages/cw-schema-codegen/playground/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
96 changes: 96 additions & 0 deletions packages/cw-schema-codegen/playground/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions packages/cw-schema-codegen/playground/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "serialization"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1.0.215", features = ["derive", "serde_derive"] }
serde_json = "1.0.133"
49 changes: 49 additions & 0 deletions packages/cw-schema-codegen/playground/playground.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from dataclasses import dataclass, field
from dataclasses_json import dataclass_json, config
from typing import Optional


@dataclass_json
@dataclass
class SomeEnum:
Tuple: Optional[tuple[int, int]] = field(default=None, metadata=config(exclude=lambda x: x is None))
String: Optional[str] = field(default=None, metadata=config(exclude=lambda x: x is None))

def get_variant(self):
self.Tuple


a = SomeEnum.from_json('{"String": "lidatong"}')
print(a.to_json())
a = SomeEnum.from_json('{"Tuple": [10, 20]}')
print(a.to_json())


# class Dupa:
# def __init__(self, field, variant_name):
# self.__value = field
# self.__variant_name = variant_name

# def variant_name(self):
# return self.__variant_name

# def Field1(x: tuple[int, int]):
# return Dupa(x, "Field1")

# def get_Field1(self) -> tuple[int, int]:
# if self.__variant_name != "Field1":
# raise Exception(f"Improper anyOf variant. Expected: {self.__variant_name}")
# return self.__value

# def Field2(x: str):
# return Dupa(x, "Field2")

# def get_Field2(self) -> str:
# if self.__variant_name != "Field2":
# raise Exception(f"Improper anyOf variant. Expected: {self.__variant_name}")
# return self.__value


# x = Dupa.Field1((12,12))
# print(x.variant_name())
# print(x.get_Field2())
28 changes: 28 additions & 0 deletions packages/cw-schema-codegen/playground/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

use serde::{Deserialize, Serialize};


#[derive(Serialize, Deserialize)]
pub enum SomeEnum {
Field1,
Field2(u32, u32),
Field3 {
a: String,
b: u32
}
}

#[derive(Serialize, Deserialize)]
pub enum OuterEnum {
FieldOuter1(SomeEnum),
FieldOuter2 { field: SomeEnum }
}

fn main() {
println!("{}", serde_json::to_string(&SomeEnum::Field1).unwrap());
println!("{}", serde_json::to_string(&SomeEnum::Field2(10, 23)).unwrap());
println!("{}", serde_json::to_string(&SomeEnum::Field3 {a: "sdf".to_string(), b: 12}).unwrap());

println!("{}", serde_json::to_string(&OuterEnum::FieldOuter1(SomeEnum::Field2(10, 23))).unwrap());
println!("{}", serde_json::to_string(&OuterEnum::FieldOuter2 { field: SomeEnum::Field3 {a: "sdf".to_string(), b: 12}}).unwrap());
}
3 changes: 3 additions & 0 deletions packages/cw-schema-codegen/src/python/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fn expand_node_name<'a>(
cw_schema::NodeType::HexBinary => todo!(),
cw_schema::NodeType::Timestamp => todo!(),
cw_schema::NodeType::Unit => Cow::Borrowed("void"),
_ => todo!()
}
}

Expand Down Expand Up @@ -82,6 +83,7 @@ where
.map(|item| expand_node_name(schema, &schema.definitions[*item]))
.collect(),
),
_ => todo!()
},
};

Expand Down Expand Up @@ -123,6 +125,7 @@ where
.collect(),
}
}
_ => todo!()
},
})
.collect(),
Expand Down
50 changes: 24 additions & 26 deletions packages/cw-schema-codegen/templates/python/enum.tpl.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@
# This code is @generated by cw-schema-codegen. Do not modify this manually.

/**
{% for doc in docs %}
* {{ doc }}
{% endfor %}
*/
class {{ name }}:
'''{% for doc in docs %}
{{ doc }}
{% endfor %}'''

type {{ name }} =
{% for variant in variants %}
|
def __init__(self, value, variant_name):
self.__value = value
self.__variant_name = variant_name

/**
{% for doc in variant.docs %}
* {{ doc }}
{% endfor %}
*/
def variant_name(self):
return self.__variant_name

{% for variant in variants %}
'''{% for doc in variant.docs %}
{{ doc }}
{% endfor %}'''
{% match variant.ty %}
{% when TypeTemplate::Unit %}
{ "{{ variant.name }}": {} }
{{ variant.name }} = None
{% when TypeTemplate::Tuple with (types) %}
{ "{{ variant.name }}": [{{ types|join(", ") }}] }
def {{ variant.name }}(value: tuple[{{ types|join(", ") }}]):
{{ name }} (value, "{{ name }}")
{% when TypeTemplate::Named with { fields } %}
{ "{{ variant.name }}": {
def {{ variant.name }}(value: tuple[{{ types|join(", ") }}]):
{{ name }} (value, "{{ name }}")

{{ variant.name }} = {
{% for field in fields %}
/**
{% for doc in field.docs %}
* {{ doc }}
# {{ doc }}
{% endfor %}
*/

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

export { {{ name }} };
{% endfor %}
29 changes: 29 additions & 0 deletions packages/cw-schema-codegen/tests/python_tpl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::borrow::Cow;

use askama::Template;
use cw_schema_codegen::python::template::{
EnumTemplate, EnumVariantTemplate, FieldTemplate, StructTemplate, TypeTemplate,
};

#[test]
fn simple_enum() {
let tpl = EnumTemplate {
name: Cow::Borrowed("Simple"),
docs: Cow::Borrowed(&[Cow::Borrowed("Simple enum")]),
variants: Cow::Borrowed(&[
EnumVariantTemplate {
name: Cow::Borrowed("One"),
docs: Cow::Borrowed(&[Cow::Borrowed("One variant")]),
ty: TypeTemplate::Unit,
},
EnumVariantTemplate {
name: Cow::Borrowed("Two"),
docs: Cow::Borrowed(&[Cow::Borrowed("Two variant")]),
ty: TypeTemplate::Unit,
},
]),
};

let rendered = tpl.render().unwrap();
insta::assert_snapshot!(rendered);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
source: packages/cw-schema-codegen/tests/python_tpl.rs
expression: rendered
snapshot_kind: text
---
# This code is @generated by cw-schema-codegen. Do not modify this manually.

/**
* Simple enum
*/
class Simple (Enum):


# One variant


{ "One" = {} }



# Two variant


{ "Two" = {} }

0 comments on commit e959fba

Please sign in to comment.