style(src-tauri): cargo fmt
Pure mechanical rustfmt reformat (default config, no rustfmt.toml).
This commit is contained in:
@@ -21,14 +21,22 @@ pub struct LogoAsset {
|
||||
}
|
||||
|
||||
fn sha8(bytes: &[u8]) -> String {
|
||||
Sha256::digest(bytes).iter().take(4).map(|b| format!("{b:02x}")).collect()
|
||||
Sha256::digest(bytes)
|
||||
.iter()
|
||||
.take(4)
|
||||
.map(|b| format!("{b:02x}"))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Derive the print and knockout images from `bytes` and store them content-addressed in the asset
|
||||
/// store. `existing_original` is the already stored file the bytes came from (legacy logos); without
|
||||
/// it the bytes are stored as the original. Nothing is ever deleted: issued invoices may still point at
|
||||
/// older logo files.
|
||||
fn store_logo(data_dir: &Path, bytes: &[u8], existing_original: Option<String>) -> Result<LogoAsset, String> {
|
||||
fn store_logo(
|
||||
data_dir: &Path,
|
||||
bytes: &[u8],
|
||||
existing_original: Option<String>,
|
||||
) -> Result<LogoAsset, String> {
|
||||
let derived = process_logo(bytes).map_err(|e| e.to_string())?;
|
||||
let id = sha8(bytes);
|
||||
let original_path = match existing_original {
|
||||
@@ -38,17 +46,28 @@ fn store_logo(data_dir: &Path, bytes: &[u8], existing_original: Option<String>)
|
||||
write_named_asset(data_dir, &format!("logo-{id}-original.{ext}"), bytes)?
|
||||
}
|
||||
};
|
||||
let print_path = write_named_asset(data_dir, &format!("logo-{id}-print.png"), &derived.print_png)?;
|
||||
let print_path = write_named_asset(
|
||||
data_dir,
|
||||
&format!("logo-{id}-print.png"),
|
||||
&derived.print_png,
|
||||
)?;
|
||||
let knockout_path = derived
|
||||
.knockout_png
|
||||
.as_deref()
|
||||
.map(|png| write_named_asset(data_dir, &format!("logo-{id}-knockout.png"), png))
|
||||
.transpose()?;
|
||||
Ok(LogoAsset { original_path, print_path, knockout_path, metrics: derived.metrics })
|
||||
Ok(LogoAsset {
|
||||
original_path,
|
||||
print_path,
|
||||
knockout_path,
|
||||
metrics: derived.metrics,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn import_logo_from_path(data_dir: &Path, source_path: &str) -> Result<LogoAsset, String> {
|
||||
let len = std::fs::metadata(source_path).map_err(|e| e.to_string())?.len();
|
||||
let len = std::fs::metadata(source_path)
|
||||
.map_err(|e| e.to_string())?
|
||||
.len();
|
||||
if len > MAX_INPUT_BYTES as u64 {
|
||||
return Err(crate::logo::LogoError::TooLarge.to_string());
|
||||
}
|
||||
@@ -61,7 +80,9 @@ pub fn import_logo_from_base64(data_dir: &Path, data_base64: &str) -> Result<Log
|
||||
if data_base64.len() > MAX_INPUT_BYTES / 3 * 4 + 8 {
|
||||
return Err(crate::logo::LogoError::TooLarge.to_string());
|
||||
}
|
||||
let bytes = STANDARD.decode(data_base64.as_bytes()).map_err(|e| e.to_string())?;
|
||||
let bytes = STANDARD
|
||||
.decode(data_base64.as_bytes())
|
||||
.map_err(|e| e.to_string())?;
|
||||
store_logo(data_dir, &bytes, None)
|
||||
}
|
||||
|
||||
@@ -74,9 +95,11 @@ fn metrics_json(metrics: &LogoMetrics) -> Result<String, String> {
|
||||
/// original. Returns whether anything changed.
|
||||
pub fn ensure_logo_derived_impl(conn: &Connection, data_dir: &Path) -> Result<bool, String> {
|
||||
let (logo_path, meta): (Option<String>, String) = conn
|
||||
.query_row("SELECT logo_path, logo_meta FROM app_settings WHERE id = 1", [], |r| {
|
||||
Ok((r.get(0)?, r.get(1)?))
|
||||
})
|
||||
.query_row(
|
||||
"SELECT logo_path, logo_meta FROM app_settings WHERE id = 1",
|
||||
[],
|
||||
|r| Ok((r.get(0)?, r.get(1)?)),
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let Some(logo_path) = logo_path.filter(|p| !p.trim().is_empty()) else {
|
||||
return Ok(false);
|
||||
@@ -86,11 +109,20 @@ pub fn ensure_logo_derived_impl(conn: &Connection, data_dir: &Path) -> Result<bo
|
||||
}
|
||||
let file = resolve_asset(data_dir, &logo_path)?;
|
||||
let bytes = std::fs::read(&file).map_err(|e| e.to_string())?;
|
||||
let asset = store_logo(data_dir, &bytes, Some(relative_asset_path(data_dir, &logo_path)?))?;
|
||||
let asset = store_logo(
|
||||
data_dir,
|
||||
&bytes,
|
||||
Some(relative_asset_path(data_dir, &logo_path)?),
|
||||
)?;
|
||||
conn.execute(
|
||||
"UPDATE app_settings SET logo_path = ?1, logo_original_path = ?2, logo_knockout_path = ?3,
|
||||
logo_meta = ?4 WHERE id = 1",
|
||||
params![asset.print_path, asset.original_path, asset.knockout_path, metrics_json(&asset.metrics)?],
|
||||
params![
|
||||
asset.print_path,
|
||||
asset.original_path,
|
||||
asset.knockout_path,
|
||||
metrics_json(&asset.metrics)?
|
||||
],
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(true)
|
||||
@@ -161,7 +193,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
let mut out = Vec::new();
|
||||
DynamicImage::ImageRgba8(img).write_to(&mut Cursor::new(&mut out), ImageFormat::Png).unwrap();
|
||||
DynamicImage::ImageRgba8(img)
|
||||
.write_to(&mut Cursor::new(&mut out), ImageFormat::Png)
|
||||
.unwrap();
|
||||
out
|
||||
}
|
||||
|
||||
@@ -180,16 +214,30 @@ mod tests {
|
||||
let bytes = padded_png();
|
||||
let asset = import_logo_from_base64(dir.path(), &STANDARD.encode(&bytes)).unwrap();
|
||||
let id = sha8(&bytes);
|
||||
assert_eq!(asset.original_path, format!("assets/logo-{id}-original.png"));
|
||||
assert_eq!(
|
||||
asset.original_path,
|
||||
format!("assets/logo-{id}-original.png")
|
||||
);
|
||||
assert_eq!(asset.print_path, format!("assets/logo-{id}-print.png"));
|
||||
assert_eq!(asset.knockout_path.as_deref(), Some(format!("assets/logo-{id}-knockout.png").as_str()));
|
||||
assert_eq!(
|
||||
asset.knockout_path.as_deref(),
|
||||
Some(format!("assets/logo-{id}-knockout.png").as_str())
|
||||
);
|
||||
assert_eq!((asset.metrics.width, asset.metrics.height), (100, 20));
|
||||
assert_eq!(std::fs::read(dir.path().join(&asset.original_path)).unwrap(), bytes);
|
||||
assert_eq!(
|
||||
std::fs::read(dir.path().join(&asset.original_path)).unwrap(),
|
||||
bytes
|
||||
);
|
||||
for rel in [&asset.print_path, asset.knockout_path.as_ref().unwrap()] {
|
||||
assert!(resolve_asset(dir.path(), rel).is_ok());
|
||||
}
|
||||
// The same bytes land on the same names.
|
||||
assert_eq!(import_logo_from_base64(dir.path(), &STANDARD.encode(&bytes)).unwrap().print_path, asset.print_path);
|
||||
assert_eq!(
|
||||
import_logo_from_base64(dir.path(), &STANDARD.encode(&bytes))
|
||||
.unwrap()
|
||||
.print_path,
|
||||
asset.print_path
|
||||
);
|
||||
let json = serde_json::to_value(&asset).unwrap();
|
||||
assert_eq!(json["metrics"]["kind"], "wordmark");
|
||||
assert_eq!(json["metrics"]["opaqueBackground"], false);
|
||||
@@ -220,7 +268,8 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
let conn = crate::db::open_in_memory().unwrap();
|
||||
let legacy = write_named_asset(dir.path(), "logo-legacy.png", &padded_png()).unwrap();
|
||||
conn.execute("UPDATE app_settings SET logo_path = ?1", [&legacy]).unwrap();
|
||||
conn.execute("UPDATE app_settings SET logo_path = ?1", [&legacy])
|
||||
.unwrap();
|
||||
|
||||
assert!(ensure_logo_derived_impl(&conn, dir.path()).unwrap());
|
||||
let (logo, original, knockout, meta) = logo_columns(&conn);
|
||||
@@ -243,7 +292,8 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
let conn = crate::db::open_in_memory().unwrap();
|
||||
assert!(!ensure_logo_derived_impl(&conn, dir.path()).unwrap());
|
||||
conn.execute("UPDATE app_settings SET logo_path = 'assets/gone.png'", []).unwrap();
|
||||
conn.execute("UPDATE app_settings SET logo_path = 'assets/gone.png'", [])
|
||||
.unwrap();
|
||||
assert!(ensure_logo_derived_impl(&conn, dir.path()).is_err());
|
||||
// Left untouched so a later start can retry.
|
||||
assert_eq!(logo_columns(&conn).0.as_deref(), Some("assets/gone.png"));
|
||||
|
||||
Reference in New Issue
Block a user