yog_cli/content/import/
mod.rs1mod bbmodel;
14mod blocks;
15mod build;
16mod fields;
17mod font;
18mod model;
19mod pack;
20mod target;
21
22pub(crate) use font::copy_path as font_copy_path;
23
24use target::Target;
25
26const USAGE: &str = "usage:\n yog import resourcepack <pack.zip|dir> [--model <ns:block/name|ns:item/name>] [--all] [--force]\n yog import bbmodel <file.bbmodel> [--id <name>] [--item] [--force]\n yog import font <yog:font/name> [--id <path>] [--chars <hex ranges>] [--force]";
27
28const MODEL: &str = "--model";
30const ID: &str = "--id";
31const CHARS: &str = "--chars";
32const WITH_VALUE: [&str; 3] = [MODEL, ID, CHARS];
33const FORCE: &str = "--force";
34const ALL: &str = "--all";
35const ITEM: &str = "--item";
36const FLAG: &str = "--";
38const RESOURCEPACK: &str = "resourcepack";
40const BBMODEL: &str = "bbmodel";
41
42fn positional(args: &[String]) -> Vec<&str> {
45 let mut out = Vec::new();
46 let mut skip = false;
47 for a in args.iter().skip(1) {
48 if skip {
49 skip = false;
50 } else if WITH_VALUE.contains(&a.as_str()) {
51 skip = true;
52 } else if !a.starts_with(FLAG) {
53 out.push(a.as_str());
54 }
55 }
56 out
57}
58
59pub struct Imported {
61 pub written: Vec<String>,
63 pub warnings: Vec<String>,
65}
66
67pub fn import_command(args: &[String]) -> Result<Imported, String> {
69 let flag = |name: &str| args.iter().any(|a| a == name);
70 let value = |name: &str| {
71 args.iter()
72 .position(|a| a == name)
73 .and_then(|i| args.get(i + 1))
74 .map(String::as_str)
75 };
76 let positional = positional(args);
77 let root = std::env::current_dir().map_err(|e| e.to_string())?;
78 let mod_id = read_mod_id(&root)?;
79 let mut target = Target {
80 root: root.clone(),
81 ns: super::valid_namespace(&mod_id).then_some(mod_id),
82 force: flag(FORCE),
83 written: Vec::new(),
84 warnings: Vec::new(),
85 };
86 match (args.first().map(String::as_str), positional.first()) {
87 (Some(RESOURCEPACK), Some(src)) => {
88 let pack = pack::Pack::open(&root.join(src))?;
89 blocks::import_pack(&mut target, &pack, value(MODEL), flag(ALL))?;
90 }
91 (Some(BBMODEL), Some(file)) => {
92 bbmodel::import_bbmodel(&mut target, &root.join(file), value(ID), flag(ITEM))?
93 }
94 (Some(kind), Some(alias)) if kind == yog_ids::kind::FONT => {
95 font::import_font(&mut target, alias, value(ID), value(CHARS))?
96 }
97 _ => return Err(USAGE.into()),
98 }
99 if target.written.is_empty() {
100 return Err(format!(
101 "nothing imported{}",
102 target
103 .warnings
104 .iter()
105 .map(|w| format!("\n {w}"))
106 .collect::<String>()
107 ));
108 }
109 Ok(Imported {
110 written: target.written,
111 warnings: target.warnings,
112 })
113}
114
115fn read_mod_id(root: &std::path::Path) -> Result<String, String> {
117 let path = root.join(yog_ids::file::MANIFEST);
118 if !path.is_file() {
119 return Err("no yog.toml in the current directory — run `yog import` in a mod".into());
120 }
121 crate::project::manifest::YogToml::read(&path).map(|m| m.id)
122}
123
124#[cfg(test)]
125mod tests;