jtd-codegen 0.1.4

Generate code from JSON Typedef schemas
use inflector::string::singularize::to_singular;
use inflector::Inflector;

pub struct StateManager<Data> {
    path: Vec<String>,
    singularize: bool,
    must_emit: bool,
    root_name: String,

    pub data: Data,
}

impl<Data> StateManager<Data> {
    pub fn new(root_name: String, initial_data: Data) -> Self {
        StateManager {
            path: vec![],
            singularize: false,
            must_emit: false,
            root_name,
            data: initial_data,
        }
    }

    pub fn must_emit(&self) -> bool {
        self.must_emit
    }

    pub fn definition_name(&self, definition: &str) -> String {
        definition.to_pascal_case()
    }

    pub fn name(&self) -> String {
        if self.path.is_empty() {
            return self.root_name.to_pascal_case();
        }

        let out = self.path.join("_").to_pascal_case();
        if self.singularize {
            to_singular(&out)
        } else {
            out
        }
    }

    pub fn with_path_segment(
        &mut self,
        segment: String,
        f: &dyn Fn(&mut Self) -> String,
    ) -> String {
        self.path.push(segment);
        let out = self.with_must_emit(false, &|state| state.with_singularize(false, f));
        self.path.pop();

        out
    }

    pub fn with_must_emit(&mut self, must_emit: bool, f: &dyn Fn(&mut Self) -> String) -> String {
        let restore = self.must_emit;

        self.must_emit = must_emit;
        let out = f(self);
        self.must_emit = restore;

        out
    }

    pub fn with_singularize(
        &mut self,
        singularize: bool,
        f: &dyn Fn(&mut Self) -> String,
    ) -> String {
        let restore = self.singularize;

        self.singularize = singularize;
        let out = f(self);
        self.singularize = restore;

        out
    }
}