use serde_json::{json, Value};
const SANITIZE_KEYS: &[&str] = &["ix", "mn", "cix", "np", "l", "td", "cl", "ct"];
const SANITIZE_KEYS_IF_ROOT: &[&str] = &["v", "props"];
const SANITIZE_KEYS_IF_NOT_LAYER: &[&str] = &["ind"];
const SANITIZE_KEYS_IF_ASSET: &[&str] = &["fr"];
const SANITIZE_KEYS_IF_NOT_PRECOMP: &[&str] = &["sr", "st"];
const SANITIZE_KEYS_IF_VAL_IS_ZERO: &[&str] = &["ddd", "bm", "ao"];
pub fn sanitize_lottie(lottie: &mut Value) {
if let Value::Object(ref mut o) = lottie {
o.retain(|k, _| !SANITIZE_KEYS_IF_ROOT.contains(&k.as_str()));
}
sanitize_value(lottie);
}
fn sanitize_value(val: &mut Value) {
match val {
Value::Object(o) => {
o.retain(|k, _| !SANITIZE_KEYS.contains(&k.as_str()));
o.retain(|k, v| {
!(SANITIZE_KEYS_IF_VAL_IS_ZERO.contains(&k.as_str()) && *v == json!(0))
});
if let Some(Value::Number(n)) = o.get("ty") {
if let Some(ty) = n.as_i64() {
if ty != 0 {
o.retain(|k, _| !SANITIZE_KEYS_IF_NOT_PRECOMP.contains(&k.as_str()));
}
}
} else {
o.retain(|k, _| !SANITIZE_KEYS_IF_NOT_LAYER.contains(&k.as_str()));
}
if let Some(Value::String(s)) = o.get("id") {
o.retain(|k, _| !SANITIZE_KEYS_IF_ASSET.contains(&k.as_str()));
}
for (_, value) in o {
sanitize_value(value);
}
}
Value::Array(a) => {
for entry in a {
sanitize_value(entry);
}
}
_ => (),
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_root_keys() {
let mut lottie = json!({
"v": "5.1.12",
"layers": [],
"props": {
"testprop": "testvalue"
},
"subobj": {
"v": "5.1.12",
"props": {
"testprop": "testvalue"
},
}
});
let sanitized_lottie = json!({
"layers": [],
"subobj": {
"v": "5.1.12",
"props": {
"testprop": "testvalue"
},
}
});
sanitize_lottie(&mut lottie);
assert_eq!(lottie, sanitized_lottie);
}
#[test]
fn test_all_keys() {
let mut lottie = json!({
"ix": 1,
"mn": "test",
"cix": 1,
"np": 1,
"l": 1,
"td": 1,
"cl": 1,
"layers": [{
"ix": 1,
"mn": "test",
"cix": 1,
"np": 1,
"l": 1,
"td": 1,
"cl": 1,
"ct": 1,
}],
});
let sanitized_lottie = json!({
"layers": [{}],
});
sanitize_lottie(&mut lottie);
assert_eq!(lottie, sanitized_lottie);
}
#[test]
fn test_not_layer_keys() {
let mut lottie = json!({
"ind": 1,
"layers": [{
"ty": 1,
"ind": 2,
"shapes": [{
"ind": 3,
"ty": "g"
}]
}],
});
let sanitized_lottie = json!({
"layers": [{
"ty": 1,
"ind": 2,
"shapes": [{
"ty": "g"
}]
}],
});
sanitize_lottie(&mut lottie);
assert_eq!(lottie, sanitized_lottie);
}
#[test]
fn test_not_precomp_keys() {
let mut lottie = json!({
"layers": [{
"ty": 1,
"sr": 1,
"st": 1,
},{
"ty": 0,
"sr": 1,
"st": 1,
}],
});
let sanitized_lottie = json!({
"layers": [{
"ty": 1,
},{
"ty": 0,
"sr": 1,
"st": 1,
}],
});
sanitize_lottie(&mut lottie);
assert_eq!(lottie, sanitized_lottie);
}
#[test]
fn test_zero_val_keys() {
let mut lottie = json!({
"layers": [{
"ddd": 0,
"bm": 0,
"ao": 0,
},{
"ddd": 1,
"bm": 1,
"ao": 1,
}],
});
let sanitized_lottie = json!({
"layers": [{
},{
"ddd": 1,
"bm": 1,
"ao": 1,
}],
});
sanitize_lottie(&mut lottie);
assert_eq!(lottie, sanitized_lottie);
}
#[test]
fn test_asset_keys() {
let mut lottie = json!({
"fr": 30,
"assets": [{
"fr": 30,
"id": "test"
}],
});
let sanitized_lottie = json!({
"fr": 30,
"assets": [{
"id": "test"
}],
});
sanitize_lottie(&mut lottie);
assert_eq!(lottie, sanitized_lottie);
}
}