mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-05-10 05:50:02 +00:00
Leon template library (#766)
* leon: first implementation * Update crates/leon/src/values.rs Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com> * Workaround orphan rules to make API more intuitive * Fmt * Clippy * Use CoW * Use cow for items too * Test that const construction works * leon: Initial attempt at O(n) parser * leon: finish parser (except escapes) * leon: Improve ergonomics of compile-time templates * Document helpers * leon: Docs tweaks * leon: Use macro to minimise parser tests * leon: add escapes to parser * leon: test escapes preceding keys * leon: add multibyte tests * leon: test escapes following keys * Format * Debug * leon: Don't actually need to keep track of the key * leon: Parse to vec first * leon: there's actually no need for string cows * leon: reorganise and redo macro now that there's no coww * Well that was silly * leon: Adjust text end when pushing * leon: catch unbalanced keys * Add error tests * leon: Catch unfinished escape * Comment out debugging * leon: fuzz * Clippy * leon: Box parse error * leon: &dyn instead of impl * Can't impl FromStr, so rename to parse * Add Vec<> to values * leon: Add benches for ways to supply values * leon: Add bench comparing to std and tt * Fix fuzz * Fmt * Split ParseError and RenderError * Make miette optional * Remove RenderError lifetime * Simplify ParseError type schema * Write concrete Values types instead of generics * Add license files * Reduce criterion deps * Make default a cow * Add a CLI leon tool * Fix tests * Clippy * Disable cli by default * Avoid failing the build when cli is off * Add to ci * Update crates/leon/src/main.rs Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com> * Update crates/leon/Cargo.toml Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com> * Bump version * Error not transparent * Diagnostic can do forwarding * Simplify error type * Expand doc examples * Generic Values for Hash and BTree maps * One more borrowed * Forward implementations * More generics * Add has_keys * Lock stdout in leon tool * No more debug comments in parser * Even more generics * Macros to reduce bench duplication * Further simplify error * Fix leon main * Stable support * Clippy --------- Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
daf8cdd010
commit
2227d363f7
20 changed files with 2382 additions and 162 deletions
85
crates/leon/src/error.rs
Normal file
85
crates/leon/src/error.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
#[derive(Debug, thiserror::Error)]
|
||||
#[cfg_attr(feature = "miette", derive(miette::Diagnostic))]
|
||||
pub enum RenderError {
|
||||
/// A key was missing from the provided values.
|
||||
#[error("missing key `{0}`")]
|
||||
MissingKey(String),
|
||||
|
||||
/// An I/O error passed through from [`Template::render_into`].
|
||||
#[error("write failed: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
/// An error that can occur when parsing a template.
|
||||
///
|
||||
/// When the `miette` feature is enabled, this is a rich miette-powered error
|
||||
/// which will highlight the source of the error in the template when output
|
||||
/// (with miette's `fancy` feature). With `miette` disabled, this is opaque.
|
||||
#[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "miette", derive(miette::Diagnostic))]
|
||||
#[cfg_attr(feature = "miette", diagnostic(transparent))]
|
||||
#[error(transparent)]
|
||||
pub struct ParseError(Box<InnerParseError>);
|
||||
|
||||
/// The inner (unboxed) type of [`ParseError`].
|
||||
#[derive(Clone, Debug, thiserror::Error, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "miette", derive(miette::Diagnostic))]
|
||||
#[error("template parse failed")]
|
||||
struct InnerParseError {
|
||||
#[cfg_attr(feature = "miette", source_code)]
|
||||
src: String,
|
||||
|
||||
#[cfg_attr(feature = "miette", label("This bracket is not opening or closing anything. Try removing it, or escaping it with a backslash."))]
|
||||
unbalanced: Option<(usize, usize)>,
|
||||
|
||||
#[cfg_attr(feature = "miette", label("This escape is malformed."))]
|
||||
escape: Option<(usize, usize)>,
|
||||
|
||||
#[cfg_attr(feature = "miette", label("A key cannot be empty."))]
|
||||
key_empty: Option<(usize, usize)>,
|
||||
|
||||
#[cfg_attr(feature = "miette", label("Escapes are not allowed in keys."))]
|
||||
key_escape: Option<(usize, usize)>,
|
||||
}
|
||||
|
||||
impl ParseError {
|
||||
pub(crate) fn unbalanced(src: &str, start: usize, end: usize) -> Self {
|
||||
Self(Box::new(InnerParseError {
|
||||
src: String::from(src),
|
||||
unbalanced: Some((start, end.saturating_sub(start) + 1)),
|
||||
escape: None,
|
||||
key_empty: None,
|
||||
key_escape: None,
|
||||
}))
|
||||
}
|
||||
|
||||
pub(crate) fn escape(src: &str, start: usize, end: usize) -> Self {
|
||||
Self(Box::new(InnerParseError {
|
||||
src: String::from(src),
|
||||
unbalanced: None,
|
||||
escape: Some((start, end.saturating_sub(start) + 1)),
|
||||
key_empty: None,
|
||||
key_escape: None,
|
||||
}))
|
||||
}
|
||||
|
||||
pub(crate) fn key_empty(src: &str, start: usize, end: usize) -> Self {
|
||||
Self(Box::new(InnerParseError {
|
||||
src: String::from(src),
|
||||
unbalanced: None,
|
||||
escape: None,
|
||||
key_empty: Some((start, end.saturating_sub(start) + 1)),
|
||||
key_escape: None,
|
||||
}))
|
||||
}
|
||||
|
||||
pub(crate) fn key_escape(src: &str, start: usize, end: usize) -> Self {
|
||||
Self(Box::new(InnerParseError {
|
||||
src: String::from(src),
|
||||
unbalanced: None,
|
||||
escape: None,
|
||||
key_empty: None,
|
||||
key_escape: Some((start, end.saturating_sub(start) + 1)),
|
||||
}))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue