rtile

rtile provides a way to work with rectangular areas of text as atomic units which can be used for code generation

How to use

```rust use rtile::*; use std::collections::BTreeMap;

fn codegen() { tp!( structdef, " #[derive(Default, Debug)] @{svis}struct @{sname}{ @{smembers} } " ); let mut input: BTreeMap<&str, (bool, Vec<&str>, Vec<&str>)> = BTreeMap::new(); input.insert( "Person", ( true, vec!["name", "age", "address", "properties"], vec!["String", "u32", "Vec

", "Properties"], ), ); input.insert( "Address", ( true, vec!["street", "city", "state", "zip"], vec!["String", "String", "String", "String"], ), ); input.insert( "Properties", ( true, vec!["gender", "kids", "otherdetails"], vec!["Gender", "Option", "OtherDetails"], ), ); let mut structcodes = vec![]; for (key, value) in &input { if value.0 { kp!(svis, "pub "); } else { tp!(svis); } tp!(sname, "{}", key); let val: Vec<_> = value .1 .iter() .zip(&value.2) .collect::>() .iter() .map(|(k, v)| { if value.0 { format!("pub {}: {},", k, v) } else { format!("{}: {},", k, v) } }) .collect(); tp!(smembers, t!(val)); structcodes.push(k!(gtp!(structdef).unwrap())); } tp!( enumdef, " #[derive(Debug)] @{evis}enum @{ename}{ @{emembers} } " ); let mut input: BTreeMap<&str, (bool, Vec<&str>, Vec<&str>)> = BTreeMap::new(); input.insert( "EmploymentStatus", ( true, vec![ "Employed", "Unemployed", "Employer", "Retired", "NotApplicable", ], vec![""; 5], ), ); input.insert( "Gender", (true, vec!["Unknown", "Male", "Female"], vec![""; 3]), ); input.insert( "OtherDetails", ( true, vec!["Miscellaneous"], vec!["{education: Option, employmentstatus: EmploymentStatus,}"], ), ); let mut enumcodes = vec![]; for (key, value) in &input { if value.0 { kp!(evis, "pub "); } else { tp!(evis); } tp!(ename, "{}", key); let val: Vec<_> = value .1 .iter() .zip(&value.2) .collect::>() .iter() .map(|(k, v)| format!("{}{},", k, v)) .collect(); tp!(emembers, t!(val)); enumcodes.push(k!(gtp!(enumdef).unwrap())); } let implsdefaultenums = t!(r#" impl Default for Gender{ fn default()->Self{ Gender::Unknown } } impl Default for EmploymentStatus{ fn default()->Self{ EmploymentStatus::NotApplicable } } impl Default for OtherDetails{ fn default()->Self{ Self::Miscellaneous{ education: None, employment_status: EmploymentStatus::default(), } } } "#);

tp!(
    some_functions,
    r#"
        fn print_default_person(){
            println!("{:#?}",Person::default());
        }
    "#
);
tp!(
    main_function,
    r#"
        fn main(){
            print_default_person();
            /*
            Person {
                name: "",
                age: 0,
                address: [],
                properties: Properties {
                    gender: Unknown,
                    kids: None,
                    other_details: Miscellaneous {
                        education: None,
                        employment_status: NotApplicable,
                    },
                },
            }
            */
        }
    "#
);
struct_codes
.into_iter()
.for_each(|code_item| println!("{code_item}\n"));
enum_codes
    .into_iter()
    .for_each(|code_item| println!("{code_item}\n"));
println!("{impls_default_enums}\n");
println!(
    "{}",
    t!("
        @{some_functions}

        @{main_function}
    ")
);

}

fn main() { codegen(); } ```

Output

```rust

[derive(Default, Debug)]

pub struct Address{ pub street: String, pub city: String, pub state: String, pub zip: String, }

[derive(Default, Debug)]

pub struct Person{ pub name: String, pub age: u32, pub address: Vec

, pub properties: Properties, }

[derive(Default, Debug)]

pub struct Properties{ pub gender: Gender, pub kids: Option, pub other_details: OtherDetails, }

[derive(Debug)]

pub enum EmploymentStatus{ Employed, Unemployed, Employer, Retired, NotApplicable, }

[derive(Debug)]

pub enum Gender{ Unknown, Male, Female, }

[derive(Debug)]

pub enum OtherDetails{ Miscellaneous{education: Option, employment_status: EmploymentStatus,}, }

impl Default for Gender{ fn default()->Self{ Gender::Unknown } } impl Default for EmploymentStatus{ fn default()->Self{ EmploymentStatus::NotApplicable } } impl Default for OtherDetails{ fn default()->Self{ Self::Miscellaneous{ education: None, employment_status: EmploymentStatus::default(), } } }

fn printdefaultperson(){ println!("{:#?}",Person::default()); }

fn main(){ printdefaultperson(); /* Person { name: "", age: 0, address: [], properties: Properties { gender: Unknown, kids: None, otherdetails: Miscellaneous { education: None, employmentstatus: NotApplicable, }, }, } */ } ```