c2pa_ml/manifest.rs
1//! The manifest payload written into a model, and the reserved metadata keys
2//! it is stored under.
3
4/// The reserved metadata key carrying an embedded C2PA Manifest Store.
5pub(crate) const STORE_KEY: &str = "c2pa.manifest";
6
7/// The reserved metadata key carrying a remote (or side-car) manifest URI.
8pub(crate) const URI_KEY: &str = "c2pa.manifest.uri";
9
10/// What to associate with a model: an embedded Manifest Store, a remote manifest
11/// URI, or both.
12///
13/// Each supported format stores these in the same reserved keys
14/// (`c2pa.manifest` / `c2pa.manifest.uri`) within its native metadata slot.
15#[derive(Debug, Clone, PartialEq, Eq, Default)]
16pub struct ManifestSource {
17 /// URI of the active manifest. The caller fetches the bytes; this crate
18 /// performs no network I/O.
19 pub active_manifest_uri: Option<String>,
20 /// Embedded C2PA Manifest Store bytes (JUMBF).
21 pub manifest_store: Option<Vec<u8>>,
22}
23
24impl ManifestSource {
25 /// Embed a Manifest Store directly in the model.
26 pub fn embedded(manifest_store: Vec<u8>) -> Self {
27 Self {
28 active_manifest_uri: None,
29 manifest_store: Some(manifest_store),
30 }
31 }
32
33 /// Reference a remote (or side-car) manifest by URI.
34 pub fn remote(uri: impl Into<String>) -> Self {
35 Self {
36 active_manifest_uri: Some(uri.into()),
37 manifest_store: None,
38 }
39 }
40
41 /// Embed a Manifest Store and record the active manifest URI.
42 pub fn both(uri: impl Into<String>, manifest_store: Vec<u8>) -> Self {
43 Self {
44 active_manifest_uri: Some(uri.into()),
45 manifest_store: Some(manifest_store),
46 }
47 }
48
49 /// True when neither a store nor a URI is present.
50 pub(crate) fn is_empty(&self) -> bool {
51 self.active_manifest_uri.is_none() && self.manifest_store.is_none()
52 }
53}