Skip to content

Commit

Permalink
feat: term-svg for snapshotting of terminal styling
Browse files Browse the repository at this point in the history
Fixes #124
  • Loading branch information
epage committed Feb 18, 2024
1 parent f10834f commit b6fda97
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 4 deletions.
44 changes: 44 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/snapbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ examples = ["dep:escargot"]

## Snapshotting of json
json = ["structured-data", "dep:serde_json"]
## Snapshotting of term styling
term-svg = ["structured-data", "dep:anstyle-svg"]
## Snapshotting of structured data
structured-data = ["dep:serde_json"]

Expand Down Expand Up @@ -91,6 +93,7 @@ anstream = { version = "0.6.7", optional = true }
document-features = { version = "0.2.6", optional = true }

serde_json = { version = "1.0.85", optional = true}
anstyle-svg = { version = "0.1.0", optional = true }

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.52.0", features = ["Win32_Foundation"], optional = true }
Expand Down
4 changes: 4 additions & 0 deletions crates/snapbox/src/data/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub enum DataFormat {
Text,
#[cfg(feature = "json")]
Json,
#[cfg(feature = "term-svg")]
TermSvg,
}

impl DataFormat {
Expand All @@ -16,6 +18,8 @@ impl DataFormat {
Self::Text => "txt",
#[cfg(feature = "json")]
Self::Json => "json",
#[cfg(feature = "term-svg")]
Self::TermSvg => "term.svg",
}
}
}
52 changes: 48 additions & 4 deletions crates/snapbox/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ enum DataInner {
Text(String),
#[cfg(feature = "json")]
Json(serde_json::Value),
#[cfg(feature = "term-svg")]
TermSvg(String),
}

impl Data {
Expand Down Expand Up @@ -181,18 +183,38 @@ impl Data {
.map_err(|e| format!("Failed to read {}: {}", path.display(), e))?;
Self::json(serde_json::from_str::<serde_json::Value>(&data).unwrap())
}
#[cfg(feature = "term-svg")]
DataFormat::TermSvg => {
let data = std::fs::read_to_string(path)
.map_err(|e| format!("Failed to read {}: {}", path.display(), e))?;
Self::from(DataInner::TermSvg(data))
}
},
None => {
let data = std::fs::read(path)
.map_err(|e| format!("Failed to read {}: {}", path.display(), e))?;
let data = Self::binary(data);
match path
.extension()

let file_name = path
.file_name()
.and_then(|e| e.to_str())
.unwrap_or_default()
{
.unwrap_or_default();
let (file_stem, mut ext) = file_name.split_once('.').unwrap_or((file_name, ""));
if file_stem.is_empty() {
(_, ext) = file_stem.split_once('.').unwrap_or((file_name, ""));
}
match ext {
#[cfg(feature = "json")]
"json" => data.coerce_to(DataFormat::Json),
#[cfg(feature = "term-svg")]
"term.svg" => {
let data = data.coerce_to(DataFormat::Text);
let inner = match data.inner {
DataInner::Text(text) => DataInner::TermSvg(text),
other => other,
};
inner.into()
}
_ => data.coerce_to(DataFormat::Text),
}
}
Expand Down Expand Up @@ -244,6 +266,8 @@ impl Data {
DataInner::Text(data) => Some(data.to_owned()),
#[cfg(feature = "json")]
DataInner::Json(value) => Some(serde_json::to_string_pretty(value).unwrap()),
#[cfg(feature = "term-svg")]
DataInner::TermSvg(data) => Some(data.to_owned()),
}
}

Expand All @@ -256,6 +280,8 @@ impl Data {
DataInner::Json(value) => {
serde_json::to_vec_pretty(value).map_err(|err| format!("{err}").into())
}
#[cfg(feature = "term-svg")]
DataInner::TermSvg(data) => Ok(data.clone().into_bytes()),
}
}

Expand All @@ -267,6 +293,8 @@ impl Data {
(DataInner::Text(inner), DataFormat::Text) => Self::text(inner),
#[cfg(feature = "json")]
(DataInner::Json(inner), DataFormat::Json) => Self::json(inner),
#[cfg(feature = "term-svg")]
(DataInner::TermSvg(inner), DataFormat::TermSvg) => inner.into(),
(DataInner::Binary(inner), _) => {
if is_binary(&inner) {
Self::binary(inner)
Expand Down Expand Up @@ -296,6 +324,10 @@ impl Data {
Err(_) => Self::text(inner),
}
}
#[cfg(feature = "term-svg")]
(DataInner::Text(inner), DataFormat::TermSvg) => {
DataInner::TermSvg(anstyle_svg::Term::new().render_svg(&inner)).into()
}
(inner, DataFormat::Binary) => {
let remake: Self = inner.into();
Self::binary(remake.to_bytes().expect("error case handled"))
Expand All @@ -310,6 +342,14 @@ impl Data {
remake
}
}
// reachable if more than one structured data format is enabled
#[allow(unreachable_patterns)]
#[cfg(feature = "json")]
(inner, DataFormat::Json) => inner.into(),
// reachable if more than one structured data format is enabled
#[allow(unreachable_patterns)]
#[cfg(feature = "term-svg")]
(inner, DataFormat::TermSvg) => inner.into(),
};
data.source = self.source;
data
Expand All @@ -323,6 +363,8 @@ impl Data {
DataInner::Text(_) => DataFormat::Text,
#[cfg(feature = "json")]
DataInner::Json(_) => DataFormat::Json,
#[cfg(feature = "term-svg")]
DataInner::TermSvg(_) => DataFormat::TermSvg,
}
}
}
Expand All @@ -344,6 +386,8 @@ impl std::fmt::Display for Data {
DataInner::Text(data) => data.fmt(f),
#[cfg(feature = "json")]
DataInner::Json(data) => serde_json::to_string_pretty(data).unwrap().fmt(f),
#[cfg(feature = "term-svg")]
DataInner::TermSvg(data) => data.fmt(f),
}
}
}
Expand Down
17 changes: 17 additions & 0 deletions crates/snapbox/src/data/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ impl Normalize for NormalizeNewlines {
normalize_value(&mut value, crate::utils::normalize_lines);
Data::json(value)
}
#[cfg(feature = "term-svg")]
DataInner::TermSvg(text) => {
let lines = crate::utils::normalize_lines(&text);
DataInner::TermSvg(lines).into()
}
};
new.source = data.source;
new
Expand All @@ -43,6 +48,11 @@ impl Normalize for NormalizePaths {
normalize_value(&mut value, crate::utils::normalize_paths);
Data::json(value)
}
#[cfg(feature = "term-svg")]
DataInner::TermSvg(text) => {
let lines = crate::utils::normalize_paths(&text);
DataInner::TermSvg(lines).into()
}
};
new.source = data.source;
new
Expand Down Expand Up @@ -82,6 +92,13 @@ impl Normalize for NormalizeMatches<'_> {
}
Data::json(value)
}
#[cfg(feature = "term-svg")]
DataInner::TermSvg(text) => {
let lines = self
.substitutions
.normalize(&text, &self.pattern.render().unwrap());
DataInner::TermSvg(lines).into()
}
};
new.source = data.source;
new
Expand Down

0 comments on commit b6fda97

Please sign in to comment.