(* ::Package:: *) (* ::Subsection::Closed:: *) (*Prepare Data*) SetDirectory@NotebookDirectory[]; styleRaw = Import["../meta-data.wl"]; styleGrouped = styleRaw["styleGroup"]; styleFlatten = DeleteDuplicatesBy[styleRaw["styleAtom"], #field&]; styleSubtype = Values[Association[(#field -> #)& /@ styleFlatten][[#subtype]]]&; (* ::Subsection::Closed:: *) (*Resolve*) (* ::Subsubsection::Closed:: *) (*Content*) buildHead = "use super::*;"; getDrawXX[item_Association] := TemplateApply[" /// Get default [<*\"`\"*>`typeOuter`<*\"`\"*>] when missing. #[serde(skip_serializing_if = \"Option::is_none\")] pub `field`: Option<`typeOuter`>, ", item ]; buildDrawXX[data_] := TemplateApply[" /// Get default style when not specified. #[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)] pub struct StyleContext {`1`} ", { getDrawXX /@ data // StringJoin } ]; getDrawXXInner[item_Association] := TemplateApply[" /// Get the [<*\"`\"*>`typeOuter`<*\"`\"*>] from theme and state. pub fn `field`(&self) -> `typeOuter` { self.once.`field`.or(self.local.`field`).or(self.theme.`field`).unwrap_or_default() } ", item ]; buildDrawXXInner[data_] := { "impl StyleResolver {", getDrawXXInner /@ data, "}" }; text = Flatten@{ buildHead, buildDrawXX @ styleFlatten, buildDrawXXInner @ styleFlatten }; Export["src/resolver/content.rs", StringRiffle[text , "\n\n"], "Text"]; (* ::Subsubsection::Closed:: *) (*Resolved*) buildHead = "use super::*;"; getDrawXX[item_Association] := TemplateApply[" /// Get the config of [<*\"`\"*>crate::`typeOuter`<*\"`\"*>] pub `field`: `typeInner`, ", item ]; buildDrawXX[data_] := { TemplateApply[" /// Get default style when not specified. #[derive(`derive`, Serialize, Deserialize)] pub struct `typeSuper` { ", data ], getDrawXX /@ styleSubtype[data] , "}" }; getDrawXXField[item_Association] := TemplateApply[ "`field`: style.`field`.unwrap_or(self.`field`()).value`isCopy`,", item ]; buildFnResolve[item_Association] := { TemplateApply[" /// Get the [<*\"`\"*>crate::`typeSuper`<*\"`\"*>] from theme and state. pub fn resolve_`field`(&self, style: crate::`typeSuper`) -> `typeSuper` { `typeSuper` { ", item ], getDrawXXField /@ styleSubtype[item] // StringJoin, "}}" }; text = Flatten@{ buildHead, buildDrawXX /@ styleGrouped, "impl StyleResolver {", buildFnResolve /@ styleGrouped, "}" }; Export["src/resolver/resolved.rs", StringRiffle[text, "\n\n"], "Text"]; (* ::Subsection::Closed:: *) (*Shapes*) (* ::Subsubsection::Closed:: *) (*Shape*) buildHead = "use super::*;"; getXX[item_Association] := TemplateApply[" /// `docs` /// `details` #[derive(`derive`, Serialize, Deserialize)] #[serde(into = \"`typeInner`\", from = \"`typeInner`\")] pub struct `typeOuter` { /// Actual value for [<*\"`\"*>StyleResolver::`field`<*\"`\"*>] pub value: `typeInner`, } ", item ]; buildXX[data_] := getXX @ data; getXXStyle[item_Association] := TemplateApply[" /// `docs`, see more in [<*\"`\"*>`typeOuter`<*\"`\"*>]. #[serde(skip_serializing_if = \"Option::is_none\")] pub `field`: Option<`typeOuter`>, ", item ]; buildXXStyle[data_] := { TemplateApply[" /// `docs` /// `details` #[derive(`derive`, Serialize, Deserialize)] pub struct `typeSuper` { ", data ], getXXStyle /@ styleSubtype@data, "}" }; text = Flatten@{ buildHead, buildXXStyle /@ styleGrouped, getXX /@ styleFlatten }; Export["src/shapes/shape.rs", StringRiffle[text , "\n\n"], "Text"]; (* ::Subsection:: *) (*Traits*) (* ::Subsubsection::Closed:: *) (*From*) buildHead = "use super::*;"; getDefault[item_Association] := TemplateApply["\ impl Default for `typeOuter` { fn default() -> Self { Self { value: `default` } } } ", item ]; buildDefault[item_] := If[MissingQ@item["default"], "", getDefault@item]; getAddXX[item_Association] := TemplateApply["\ impl From<`typeInner`> for `typeOuter` { fn from(value: `typeInner`) -> Self { Self { value } } } impl Into<`typeInner`> for `typeOuter` { fn into(self) -> `typeInner` { self.value } } ", item ]; buildFromXX[data_] := getAddXX@data; getAddSelf[item_Association] := TemplateApply["self.`field` = rhs.`field`;", item]; getSelfClone[item_Association] := TemplateApply["self.`field` = rhs.`field`.clone();", item]; buildAddSelf[data_Association] := TemplateApply["\ impl AddAssign for `3` { fn add_assign(&mut self, rhs: Self) {`1`} } impl AddAssign<&Self> for `3` { fn add_assign(&mut self, rhs: &Self) {`2`} }", { getAddSelf /@ styleSubtype@data // StringJoin, getSelfClone /@ styleSubtype@data // StringJoin, data["type"] } ]; getEq[item_Association] := TemplateApply["\ impl PartialEq for `typeOuter` { fn eq(&self, other: &f32) -> bool { self.value.eq(other) } } impl PartialOrd for `typeOuter` { fn partial_cmp(&self, other: &f32) -> Option { self.value.partial_cmp(other) } } ", item ]; buildEq[data_] := If[data["typeInner"] === "f32", getEq@data, Nothing]; text = Flatten@{ buildHead, buildDefault /@ styleFlatten, buildFromXX /@ styleFlatten, buildEq /@ styleFlatten }; Export["src/traits/convert.rs", StringRiffle[text , "\n\n"], "Text"]; (* ::Subsubsection:: *) (*AddAssign*) buildHead = "use super::*;"; getAddSuper[item_Association] := TemplateApply[" impl AddAssign<`typeOuter`> for `typeSuper` { fn add_assign(&mut self, rhs: `typeOuter`) { self.`field` = Some(rhs); } } impl AddAssign<&`typeOuter`> for `typeSuper` { fn add_assign(&mut self, rhs: &`typeOuter`) { self.`field` = Some(rhs.clone()); } } ", item ]; buildSuper[data_] := getAddSuper@data; getAddXX[item_Association] := TemplateApply[" impl AddAssign<`typeOuter`> for StyleContext { fn add_assign(&mut self, rhs: `typeOuter`) { self.`field` = Some(rhs); } } impl AddAssign<&`typeOuter`> for StyleContext { fn add_assign(&mut self, rhs: &`typeOuter`) { self.`field` = Some(rhs.clone()); } } ", item ]; buildAddXX[data_] := getAddXX@data; getAddSelf[item_Association] := TemplateApply["self.`field` = rhs.`field`;", item]; getSelfClone[item_Association] := TemplateApply["self.`field` = rhs.`field`.clone();", item]; buildAddSelf[data_Association] := TemplateApply["\ impl AddAssign for `3` { fn add_assign(&mut self, rhs: Self) {`1`} } impl AddAssign<&Self> for `3` { fn add_assign(&mut self, rhs: &Self) {`2`} }", { getAddSelf /@ styleSubtype@data // StringJoin, getSelfClone /@ styleSubtype@data // StringJoin, data["typeSuper"] } ]; upcast = Flatten@{ buildHead, buildAddXX /@ styleFlatten, buildAddSelf /@ styleGrouped }; Export["src/traits/add_assign.rs", StringRiffle[upcast , "\n\n"], "Text"]; (* ::Subsubsection:: *) (*DrawStyle*) buildHead = "use super::*;"; getDrawXX[item_Association] := TemplateApply["\ impl GraphicsStyle for `typeOuter` { fn draw_style(&self, state: &mut StyleContext) { state.`field` = Some(self.clone()); } } ", item ]; buildDrawXX[data_] := getDrawXX[data]; getDrawXXStyle[item_Association] := TemplateApply[ "state.`field` = Some(self.`field`.unwrap_or_default());", item ]; buildDrawXXStyle[data_] := TemplateApply["\ impl GraphicsStyle for `2` { fn draw_style(&self, state: &mut StyleContext) { `1` } } ", { getDrawXXStyle /@ styleSubtype@data // StringJoin, data["typeSuper"] } ]; drawStyle = Flatten@{ buildHead, buildDrawXX /@ styleFlatten, buildDrawXXStyle /@ styleGrouped }; Export["src/traits/draw_style.rs", StringRiffle[drawStyle , "\n\n"], "Text"]'