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>,
62 pub warnings: Vec<String>,
63}
64
65pub fn import_command(args: &[String]) -> Result<Imported, String> {
67 let flag = |name: &str| args.iter().any(|a| a == name);
68 let value = |name: &str| {
69 args.iter()
70 .position(|a| a == name)
71 .and_then(|i| args.get(i + 1))
72 .map(String::as_str)
73 };
74 let positional = positional(args);
75 let root = std::env::current_dir().map_err(|e| e.to_string())?;
76 let mod_id = read_mod_id(&root)?;
77 let mut target = Target {
78 root: root.clone(),
79 ns: super::valid_namespace(&mod_id).then_some(mod_id),
80 force: flag(FORCE),
81 written: Vec::new(),
82 warnings: Vec::new(),
83 };
84 match (args.first().map(String::as_str), positional.first()) {
85 (Some(RESOURCEPACK), Some(src)) => {
86 let pack = pack::Pack::open(&root.join(src))?;
87 blocks::import_pack(&mut target, &pack, value(MODEL), flag(ALL))?;
88 }
89 (Some(BBMODEL), Some(file)) => {
90 bbmodel::import_bbmodel(&mut target, &root.join(file), value(ID), flag(ITEM))?
91 }
92 (Some(kind), Some(alias)) if kind == yog_ids::kind::FONT => {
93 font::import_font(&mut target, alias, value(ID), value(CHARS))?
94 }
95 _ => return Err(USAGE.into()),
96 }
97 if target.written.is_empty() {
98 return Err(format!(
99 "nothing imported{}",
100 target
101 .warnings
102 .iter()
103 .map(|w| format!("\n {w}"))
104 .collect::<String>()
105 ));
106 }
107 Ok(Imported {
108 written: target.written,
109 warnings: target.warnings,
110 })
111}
112
113fn read_mod_id(root: &std::path::Path) -> Result<String, String> {
115 let path = root.join(yog_ids::file::MANIFEST);
116 if !path.is_file() {
117 return Err("no yog.toml in the current directory — run `yog import` in a mod".into());
118 }
119 crate::manifest::YogToml::read(&path).map(|m| m.id)
120}
121
122#[cfg(test)]
123mod tests;