Skip to content

Commit 65a48ef

Browse files
authored
fix: implement custom serialization for Extension.minimum_coco_version (#1010)
Coco's version string does not adhere to semver's spec, so we had to write a custom deserialization impl to do the conversion: ``` 0.9.1-SNPASHOT-2560 => 0.9.1-SNAPSHOT.2560 ``` But we forget to serialize versions to Coco's format when writing extensions to disk. When Coco reads extension from disk, it sees valid semantic versions, which are not expected: ``` [WAR] [third_party:167] invalid extension: [base64-converter]: field [minimum_coco_version] has invalid version: failed to parse build number 'SNAPSHOT.2560'', caused by: ['invalid digit found in string'] ``` This commit provides a custom serialization impl to fix the issue.
1 parent 0613238 commit 65a48ef

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

docs/content.en/docs/release-notes/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Information about release notes of Coco App is provided here.
1616
### 🐛 Bug fix
1717

1818
- fix: fix the abnormal input height issue #1006
19+
- fix: implement custom serialization for Extension.minimum_coco_version #1010
1920

2021
### ✈️ Improvements
2122

src-tauri/src/extension/mod.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ pub struct Extension {
135135
/// It is only for third-party extensions. Built-in extensions should always
136136
/// set this field to `None`.
137137
#[serde(deserialize_with = "deserialize_coco_semver")]
138-
#[serde(default)] // None if this field is missing
138+
#[serde(serialize_with = "serialize_coco_semver")]
139+
// None if this field is missing, required as we use custom deserilize method.
140+
#[serde(default)]
139141
minimum_coco_version: Option<SemVer>,
140142

141143
/*
@@ -419,6 +421,37 @@ where
419421
Ok(Some(semver))
420422
}
421423

424+
/// Serialize Coco SemVer to a string.
425+
///
426+
/// For a `SemVer`, there are 2 possible input cases, guarded by `to_semver()`:
427+
///
428+
/// 1. "x.y.z" => "x.y.z"
429+
/// 2. "x.y.z-SNAPSHOT.2560" => "x.y.z-SNAPSHOT-2560"
430+
fn serialize_coco_semver<S>(version: &Option<SemVer>, serializer: S) -> Result<S::Ok, S::Error>
431+
where
432+
S: serde::Serializer,
433+
{
434+
match version {
435+
Some(v) => {
436+
assert!(v.build.is_empty());
437+
438+
let s = if v.pre.is_empty() {
439+
format!("{}.{}.{}", v.major, v.minor, v.patch)
440+
} else {
441+
format!(
442+
"{}.{}.{}-{}",
443+
v.major,
444+
v.minor,
445+
v.patch,
446+
v.pre.as_str().replace('.', "-")
447+
)
448+
};
449+
serializer.serialize_str(&s)
450+
}
451+
None => serializer.serialize_none(),
452+
}
453+
}
454+
422455
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
423456
pub(crate) struct CommandAction {
424457
pub(crate) exec: String,
@@ -2150,4 +2183,31 @@ mod tests {
21502183
let deserialized: FileSystemAccess = serde_json::from_str(&serialized).unwrap();
21512184
assert_eq!(original, deserialized);
21522185
}
2186+
2187+
#[test]
2188+
fn test_serialize_coco_semver_none() {
2189+
let version: Option<SemVer> = None;
2190+
let mut serializer = serde_json::Serializer::new(Vec::new());
2191+
serialize_coco_semver(&version, &mut serializer).unwrap();
2192+
let serialized = String::from_utf8(serializer.into_inner()).unwrap();
2193+
assert_eq!(serialized, "null");
2194+
}
2195+
2196+
#[test]
2197+
fn test_serialize_coco_semver_simple() {
2198+
let version: Option<SemVer> = Some(SemVer::parse("1.2.3").unwrap());
2199+
let mut serializer = serde_json::Serializer::new(Vec::new());
2200+
serialize_coco_semver(&version, &mut serializer).unwrap();
2201+
let serialized = String::from_utf8(serializer.into_inner()).unwrap();
2202+
assert_eq!(serialized, "\"1.2.3\"");
2203+
}
2204+
2205+
#[test]
2206+
fn test_serialize_coco_semver_with_pre() {
2207+
let version: Option<SemVer> = Some(SemVer::parse("1.2.3-SNAPSHOT.1234").unwrap());
2208+
let mut serializer = serde_json::Serializer::new(Vec::new());
2209+
serialize_coco_semver(&version, &mut serializer).unwrap();
2210+
let serialized = String::from_utf8(serializer.into_inner()).unwrap();
2211+
assert_eq!(serialized, "\"1.2.3-SNAPSHOT-1234\"");
2212+
}
21532213
}

0 commit comments

Comments
 (0)