Feat: import / export fix
This commit is contained in:
@@ -11,6 +11,24 @@ use crate::{Bank, Pattern};
|
||||
const PATTERN_PREFIX: &str = "cgr:";
|
||||
const BANK_PREFIX: &str = "cgrb:";
|
||||
|
||||
pub enum ImportResult {
|
||||
Pattern(Pattern),
|
||||
Bank(Bank),
|
||||
}
|
||||
|
||||
/// Auto-detect format from the prefix and decode.
|
||||
pub fn import_auto(text: &str) -> Result<ImportResult, ShareError> {
|
||||
// Strip everything non-ASCII — valid share strings are pure ASCII
|
||||
let clean: String = text.chars().filter(|c| c.is_ascii_graphic()).collect();
|
||||
if clean.starts_with(BANK_PREFIX) {
|
||||
Ok(ImportResult::Bank(decode(&clean, BANK_PREFIX)?))
|
||||
} else if clean.starts_with(PATTERN_PREFIX) {
|
||||
Ok(ImportResult::Pattern(decode(&clean, PATTERN_PREFIX)?))
|
||||
} else {
|
||||
Err(ShareError::InvalidPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
/// Error during pattern or bank import/export.
|
||||
#[derive(Debug)]
|
||||
pub enum ShareError {
|
||||
@@ -63,7 +81,12 @@ fn encode<T: serde::Serialize>(value: &T, prefix: &str) -> Result<String, ShareE
|
||||
fn decode<T: serde::de::DeserializeOwned>(text: &str, prefix: &str) -> Result<T, ShareError> {
|
||||
let text = text.trim();
|
||||
let payload = text.strip_prefix(prefix).ok_or(ShareError::InvalidPrefix)?;
|
||||
let compressed = URL_SAFE_NO_PAD.decode(payload).map_err(ShareError::Base64)?;
|
||||
// Strip invisible characters that clipboard managers / web copies can inject
|
||||
let clean: String = payload
|
||||
.chars()
|
||||
.filter(|c| c.is_ascii_alphanumeric() || *c == '-' || *c == '_')
|
||||
.collect();
|
||||
let compressed = URL_SAFE_NO_PAD.decode(&clean).map_err(ShareError::Base64)?;
|
||||
let packed = decompress(&compressed)?;
|
||||
rmp_serde::from_slice(&packed).map_err(ShareError::Deserialize)
|
||||
}
|
||||
@@ -146,7 +169,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn bad_base64() {
|
||||
assert!(matches!(import("cgr:!!!"), Err(ShareError::Base64(_))));
|
||||
assert!(import("cgr:not-valid-data").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user