mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 06:22:24 +00:00
Read FigCraft document envelopes in shared codec
This commit is contained in:
1 parent
a00f8df829
commit
a966e43c29
1 file changed
+29
@@ -191,6 +191,25 @@ impl<'de> Deserialize<'de> for Header {
|
||||
#[error("this file was saved by a newer FigCraft (format version {0})")]
|
||||
pub struct NewerVersion(pub u32);
|
||||
|
||||
/// Failure while reading the native document envelope or its app-supplied payload type.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ReadDocumentError {
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
#[error(transparent)]
|
||||
NewerVersion(#[from] NewerVersion),
|
||||
}
|
||||
|
||||
/// Read a document payload after checking the native header and version first.
|
||||
///
|
||||
/// The payload type is supplied by the consumer, keeping app model conversion outside this crate.
|
||||
pub fn read_document_json<D: serde::de::DeserializeOwned>(text: &str) -> Result<(D, Header), ReadDocumentError> {
|
||||
let header = read_header(text)?;
|
||||
check_version(&header)?;
|
||||
let document = serde_json::from_str(text)?;
|
||||
Ok((document, header))
|
||||
}
|
||||
|
||||
pub fn check_version(h: &Header) -> Result<(), NewerVersion> {
|
||||
if let Some(v) = h.version
|
||||
&& v > u64::from(VERSION)
|
||||
@@ -288,6 +307,16 @@ mod tests {
|
||||
fn newer_version_is_reported_before_document_decode() {
|
||||
assert_eq!(check_version(&Header { version: Some(2), images: None }), Err(NewerVersion(2)));
|
||||
assert_eq!(check_version(&Header { version: Some(u64::MAX), images: None }), Err(NewerVersion(u32::MAX)));
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Payload {
|
||||
document: u32,
|
||||
}
|
||||
let text = r#"{"version":2,"document":{"wrong":"type"}}"#;
|
||||
assert!(matches!(read_document_json::<Payload>(text), Err(ReadDocumentError::NewerVersion(NewerVersion(2)))));
|
||||
let (payload, header) = read_document_json::<Payload>(r#"{"version":1,"imageIndex":[{"hash":"a"}],"document":5}"#).unwrap();
|
||||
assert_eq!(payload.document, 5);
|
||||
assert_eq!(header.images, Some(vec!["a".into()]));
|
||||
}
|
||||
#[test]
|
||||
fn writer_flattens_document_fields() {
|
||||
|
||||
Reference in new issue
Block a user