Skip to main content

co_primitives/types/
co_reference.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 1io BRANDGUARDIAN GmbH
3
4use crate::{Block, BlockSerializer, BlockSerializerError, KnownMultiCodec};
5use serde::{Deserialize, Serialize};
6
7/// Wrapps a reference/link/Cid and applies attributes useful in context of a Co.
8/// - A [`CoReference`] should be encoded with [`crate::KnownMultiCodec::CoReference`].
9/// - A [`CoReference`] should be used with a narrow scope so that only the links to it are moved around.
10/// - A [`CoReference`] should be used for cross Co references to state and heads as this has special semantics for
11///   example encryption mapping.
12///
13/// ## FAQ
14/// ### When to use [`CoReference::Weak`] and when [`co_primitives::WeakCid`]?
15/// Use [`CoReference::Weak`] when you want to reference a root.
16/// When the garbage collection reaches a [`CoReference::Weak`] it will not try to keep it alve with its parent.
17/// Example: Keeping a historic root for reference or fast traversing.
18///
19/// Use [`co_primitives::WeakCid`] when the reference should not been handled as a link and will not be
20/// accessed/traversed using this reference.
21#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
22#[non_exhaustive]
23pub enum CoReference<T> {
24	/// Handle the reference as a weak reference. Used for reference counting.
25	#[serde(rename = "w")]
26	Weak(T),
27}
28impl<T> CoReference<T> {
29	pub fn into_value(self) -> T {
30		match self {
31			CoReference::Weak(t) => t,
32		}
33	}
34
35	pub fn to_block(&self) -> Result<Block, BlockSerializerError>
36	where
37		T: Serialize,
38	{
39		BlockSerializer::new_codec(KnownMultiCodec::CoReference).serialize(self)
40	}
41}
42impl<T> AsRef<T> for CoReference<T> {
43	fn as_ref(&self) -> &T {
44		match self {
45			CoReference::Weak(t) => t,
46		}
47	}
48}
49
50#[cfg(test)]
51mod tests {
52	use super::CoReference;
53	use crate::{from_cbor, to_cbor};
54	use serde::de::IgnoredAny;
55
56	#[test]
57	fn test_serialize() {
58		let item = CoReference::Weak(1);
59		let encoded = to_cbor(&item).unwrap();
60		let decoded: CoReference<i32> = from_cbor(&encoded).unwrap();
61		assert_eq!(decoded, item);
62		let decoded: CoReference<IgnoredAny> = from_cbor(&encoded).unwrap();
63		assert_eq!(decoded, CoReference::Weak(IgnoredAny));
64	}
65}