diff options
author | Kim Altintop <kim@eagain.io> | 2023-03-29 13:20:08 +0200 |
---|---|---|
committer | Kim Altintop <kim@eagain.io> | 2023-03-29 13:20:08 +0200 |
commit | a483cc97d56a770c4ccf91dfccf790a8c2d0c9fa (patch) | |
tree | abe1fc1860def1b5f2cceae4c4da003c2f60705d /src/metadata/identity.rs | |
parent | a4d2d6ac8acb34314fba166d5b85ff06c97f0ca3 (diff) |
core: version each metadata type separately
It turns out to be preferable to be able to break one type without
affecting the other.
So instead of the global SpecVersion, use a separate FmtVersion for each
type. For compatibility, keep supporting spec_version fields (until next
major bump of the respective types' version).
Signed-off-by: Kim Altintop <kim@eagain.io>
Diffstat (limited to 'src/metadata/identity.rs')
-rw-r--r-- | src/metadata/identity.rs | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/src/metadata/identity.rs b/src/metadata/identity.rs index 8071e84..15967c4 100644 --- a/src/metadata/identity.rs +++ b/src/metadata/identity.rs @@ -11,6 +11,7 @@ use std::{ io, marker::PhantomData, num::NonZeroUsize, + ops::Deref, path::PathBuf, str::FromStr, }; @@ -46,7 +47,6 @@ use super::{ Metadata, Signature, Signed, - SpecVersion, }; use crate::{ json::{ @@ -56,6 +56,25 @@ use crate::{ metadata::git::find_parent, }; +pub const FMT_VERSION: FmtVersion = FmtVersion(super::FmtVersion::new(0, 2, 0)); + +#[derive(Clone, Eq, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +pub struct FmtVersion(super::FmtVersion); + +impl Deref for FmtVersion { + type Target = super::FmtVersion; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for FmtVersion { + fn default() -> Self { + FMT_VERSION + } +} + #[derive( Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash, serde::Serialize, serde::Deserialize, )] @@ -135,9 +154,10 @@ impl AsRef<Identity> for Verified { } } -#[derive(Clone, serde::Serialize, serde::Deserialize)] +#[derive(Clone, serde::Deserialize)] pub struct Identity { - pub spec_version: SpecVersion, + #[serde(alias = "spec_version")] + pub fmt_version: FmtVersion, pub prev: Option<ContentHash>, pub keys: KeySet<'static>, pub threshold: NonZeroUsize, @@ -188,7 +208,7 @@ impl Identity { { use error::Verification::IncompatibleSpecVersion; - if !crate::SPEC_VERSION.is_compatible(&self.spec_version) { + if !FMT_VERSION.is_compatible(&self.fmt_version) { return Err(IncompatibleSpecVersion); } @@ -259,6 +279,30 @@ impl<'a> From<&'a Identity> for Cow<'a, Identity> { } } +impl serde::Serialize for Identity { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + + let mut s = serializer.serialize_struct("Identity", 7)?; + let version_field = if self.fmt_version < FMT_VERSION { + "spec_version" + } else { + "fmt_version" + }; + s.serialize_field(version_field, &self.fmt_version)?; + s.serialize_field("prev", &self.prev)?; + s.serialize_field("keys", &self.keys)?; + s.serialize_field("threshold", &self.threshold)?; + s.serialize_field("mirrors", &self.mirrors)?; + s.serialize_field("expires", &self.expires)?; + s.serialize_field("custom", &self.custom)?; + s.end() + } +} + fn verify_signatures<'a, S>( payload: &[u8], threshold: NonZeroUsize, |