Use leon for template in binstalk & detect malformed pkg-url/pkg-fmt early (#933)

Fixed #851

* Add new dep leon to crate binstalk
* Add new variant `BinstallError::Template{Parse, Render}Error`
* Use `leon::Template` in mod `bins`
* Use `leon::Template` in mod `fetchers::gh_crate_meta`
* Refactor mod `bins`: Rm unused associated fn & fields from `Context`
* Simplify unit testing in mod `fetchers::gh_crate_meta`
* Rm soft-deprecated field `fetchers::gh_crate_meta::Context::format`
  and change the `match` to resolve `archive` => `self.archive_format`.
* Make macro_rules `leon::template!` far easier to use
* Construct `leon::Template<'_>` as constant in `gh_crate_meta::hosting`
* Simplify `leon::Values` trait
   Change its method `get_value` signature to
   
   ```rust
       fn get_value(&self, key: &str) -> Option<Cow<'_, str>>;
   ```
   
   Now, `ValuesFn` also accepts non-`'static` function, but now
   `leon::Values` is only implemented for `&ValuesFn<F>` now.
   
   This makes it a little bit more cumbersome to use but I think it's a
   reasonable drawback.
* Rm `Send` bound req from `ValuesFn`
* Impl new fn `leon::Template::cast`
   for casting `Template<'s>` to `Template<'t>` where `'s: 't`
* Rename `leon::Template::has_keys` => `has_any_of_keys`
* Make checking whether format related keys are present more robust
* Optimize `GhCrateMeta::launch_baseline_find_tasks`: Skip checking all fmt ext
   if none of the format related keys ("format", "archive-format",
   "archive-suffix") are present.
* Only ret `.exe` in `PkgFmt::extensions` on windows
   by adding a new param `is_windows: bool`
* Improve debug msg in `GhCrateMeta::fetch_and_extract`
* Add warnings to `GhCrateMeta::find`
* Rm dep tinytemplate
* `impl<'s, 'rhs: 's> ops::AddAssign<&Template<'rhs>> for Template<'s>`
* `impl<'s, 'rhs: 's> ops::AddAssign<Template<'rhs>> for Template<'s>`
* `impl<'s, 'item: 's> ops::AddAssign<Item<'item>> for Template<'s>`
* `impl<'s, 'item: 's> ops::AddAssign<&Item<'item>> for Template<'s>`
* `impl<'s, 'rhs: 's> ops::Add<Template<'rhs>> for Template<'s>` (improved existing `Add` impl)
* `impl<'s, 'rhs: 's> ops::Add<&Template<'rhs>> for Template<'s>`
* `impl<'s, 'item: 's> ops::Add<Item<'item>> for Template<'s>`
* `impl<'s, 'item: 's> ops::Add<&Item<'item>> for Template<'s>`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
Co-authored-by: Félix Saparelli <felix@passcod.name>
This commit is contained in:
Jiahao XU 2023-03-26 16:11:10 +11:00 committed by GitHub
parent 47d4aeaa96
commit a27d5aebf6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 512 additions and 312 deletions

View file

@ -77,7 +77,7 @@ impl<'s> Template<'s> {
#[cfg(test)]
mod test_valid {
use crate::{template, Item::*, Template};
use crate::{template, Template};
#[test]
fn empty() {
@ -88,34 +88,31 @@ mod test_valid {
#[test]
fn no_keys() {
let template = Template::parse("hello world").unwrap();
assert_eq!(template, template!(Text("hello world")));
assert_eq!(template, template!("hello world"));
}
#[test]
fn leading_key() {
let template = Template::parse("{salutation} world").unwrap();
assert_eq!(template, template!(Key("salutation"), Text(" world")));
assert_eq!(template, template!({ "salutation" }, " world"));
}
#[test]
fn trailing_key() {
let template = Template::parse("hello {name}").unwrap();
assert_eq!(template, template!(Text("hello "), Key("name")));
assert_eq!(template, template!("hello ", { "name" }));
}
#[test]
fn middle_key() {
let template = Template::parse("hello {name}!").unwrap();
assert_eq!(template, template!(Text("hello "), Key("name"), Text("!")));
assert_eq!(template, template!("hello ", { "name" }, "!"));
}
#[test]
fn middle_text() {
let template = Template::parse("{salutation} good {title}").unwrap();
assert_eq!(
template,
template!(Key("salutation"), Text(" good "), Key("title"))
);
assert_eq!(template, template!({ "salutation" }, " good ", { "title" }));
}
#[test]
@ -131,13 +128,13 @@ mod test_valid {
assert_eq!(
template,
template!(
Text("\n And if thy native country was "),
Key("ancient civilisation"),
Text(",\n What need to slight thee? Came not "),
Key("hero"),
Text(" thence,\n Who gave to "),
Key("country"),
Text(" her books and art of writing?\n "),
"\n And if thy native country was ",
{ "ancient civilisation" },
",\n What need to slight thee? Came not ",
{ "hero" },
" thence,\n Who gave to ",
{ "country" },
" her books and art of writing?\n ",
)
);
}
@ -145,19 +142,19 @@ mod test_valid {
#[test]
fn key_no_whitespace() {
let template = Template::parse("{word}").unwrap();
assert_eq!(template, template!(Key("word")));
assert_eq!(template, template!({ "word" }));
}
#[test]
fn key_leading_whitespace() {
let template = Template::parse("{ word}").unwrap();
assert_eq!(template, template!(Key("word")));
assert_eq!(template, template!({ "word" }));
}
#[test]
fn key_trailing_whitespace() {
let template = Template::parse("{word\n}").unwrap();
assert_eq!(template, template!(Key("word")));
assert_eq!(template, template!({ "word" }));
}
#[test]
@ -168,46 +165,31 @@ mod test_valid {
}",
)
.unwrap();
assert_eq!(template, template!(Key("word")));
assert_eq!(template, template!({ "word" }));
}
#[test]
fn key_inner_whitespace() {
let template = Template::parse("{ a word }").unwrap();
assert_eq!(template, template!(Key("a word")));
assert_eq!(template, template!({ "a word" }));
}
#[test]
fn escape_left() {
let template = Template::parse(r"this \{ single left brace").unwrap();
assert_eq!(
template,
template!(Text("this "), Text("{"), Text(" single left brace"))
);
assert_eq!(template, template!("this ", "{", " single left brace"));
}
#[test]
fn escape_right() {
let template = Template::parse(r"this \} single right brace").unwrap();
assert_eq!(
template,
template!(Text("this "), Text("}"), Text(" single right brace"))
);
assert_eq!(template, template!("this ", "}", " single right brace"));
}
#[test]
fn escape_both() {
let template = Template::parse(r"these \{ two \} braces").unwrap();
assert_eq!(
template,
template!(
Text("these "),
Text("{"),
Text(" two "),
Text("}"),
Text(" braces")
)
);
assert_eq!(template, template!("these ", "{", " two ", "}", " braces"));
}
#[test]
@ -215,15 +197,7 @@ mod test_valid {
let template = Template::parse(r"these \{\{ four \}\} braces").unwrap();
assert_eq!(
template,
template!(
Text("these "),
Text("{"),
Text("{"),
Text(" four "),
Text("}"),
Text("}"),
Text(" braces")
)
template!("these ", "{", "{", " four ", "}", "}", " braces")
);
}
@ -232,13 +206,7 @@ mod test_valid {
let template = Template::parse(r"these \\ backslashes \\\\").unwrap();
assert_eq!(
template,
template!(
Text("these "),
Text(r"\"),
Text(" backslashes "),
Text(r"\"),
Text(r"\"),
)
template!("these ", r"\", " backslashes ", r"\", r"\",)
);
}
@ -247,16 +215,7 @@ mod test_valid {
let template = Template::parse(r"\\{ a } \{{ b } \}{ c }").unwrap();
assert_eq!(
template,
template!(
Text(r"\"),
Key("a"),
Text(" "),
Text(r"{"),
Key("b"),
Text(" "),
Text(r"}"),
Key("c"),
)
template!(r"\", { "a" }, " ", r"{", { "b" }, " ", r"}", { "c" })
);
}
@ -265,44 +224,32 @@ mod test_valid {
let template = Template::parse(r"{ a }\\ { b }\{ { c }\}").unwrap();
assert_eq!(
template,
template!(
Key("a"),
Text(r"\"),
Text(" "),
Key("b"),
Text(r"{"),
Text(" "),
Key("c"),
Text(r"}"),
)
template!({ "a" }, r"\", " ", { "b" }, r"{", " ", { "c" }, r"}")
);
}
#[test]
fn multibyte_texts() {
let template = Template::parse("幸徳 {particle} 秋水").unwrap();
assert_eq!(
template,
template!(Text("幸徳 "), Key("particle"), Text(" 秋水"))
);
assert_eq!(template, template!("幸徳 ", { "particle" }, " 秋水"));
}
#[test]
fn multibyte_key() {
let template = Template::parse("The { 連盟 }").unwrap();
assert_eq!(template, template!(Text("The "), Key("連盟")));
assert_eq!(template, template!("The ", { "連盟" }));
}
#[test]
fn multibyte_both() {
let template = Template::parse("大杉 {栄}").unwrap();
assert_eq!(template, template!(Text("大杉 "), Key("")));
assert_eq!(template, template!("大杉 ", { "" }));
}
#[test]
fn multibyte_whitespace() {
let template = Template::parse("岩佐 作{ 太 }郎").unwrap();
assert_eq!(template, template!(Text("岩佐 作"), Key(""), Text("")));
assert_eq!(template, template!("岩佐 作", { "" }, ""));
}
#[test]
@ -310,26 +257,20 @@ mod test_valid {
let template = Template::parse(r"日本\{アナキスト\}連盟").unwrap();
assert_eq!(
template,
template!(
Text("日本"),
Text(r"{"),
Text("アナキスト"),
Text(r"}"),
Text("連盟")
)
template!("日本", r"{", "アナキスト", r"}", "連盟")
);
}
#[test]
fn multibyte_rtl_text() {
let template = Template::parse("محمد صايل").unwrap();
assert_eq!(template, template!(Text("محمد صايل")));
assert_eq!(template, template!("محمد صايل"));
}
#[test]
fn multibyte_rtl_key() {
let template = Template::parse("محمد {ريشة}").unwrap();
assert_eq!(template, template!(Text("محمد "), Key("ريشة")));
assert_eq!(template, template!("محمد ", { "ريشة" }));
}
}