Skip to main content

miden_mast_package/package/
id.rs

1use alloc::{string::ToString, sync::Arc};
2use core::{borrow::Borrow, fmt, ops::Deref};
3
4#[cfg(all(feature = "arbitrary", test))]
5use miden_core::serde::{Deserializable, Serializable};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9/// A type that represents the unique identifier for packages in a registry.
10///
11/// This is a simple newtype wrapper around an [`Arc<str>`] so that we can provide some ergonomic
12/// conveniences, and allow migration to some other type in the future with minimal downstream
13/// impact, if any.
14#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[cfg_attr(feature = "serde", serde(transparent))]
17#[cfg_attr(
18    all(feature = "arbitrary", test),
19    miden_test_serde_macros::serde_test(binary_serde(true))
20)]
21#[repr(transparent)]
22pub struct PackageId(Arc<str>);
23
24impl PackageId {
25    #[inline(always)]
26    pub fn into_inner(self) -> Arc<str> {
27        self.0
28    }
29}
30
31impl PartialEq<str> for PackageId {
32    fn eq(&self, other: &str) -> bool {
33        self.0.as_ref() == other
34    }
35}
36
37impl Borrow<str> for PackageId {
38    fn borrow(&self) -> &str {
39        &self.0
40    }
41}
42
43impl Borrow<Arc<str>> for PackageId {
44    fn borrow(&self) -> &Arc<str> {
45        &self.0
46    }
47}
48
49impl fmt::Display for PackageId {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        fmt::Display::fmt(&self.0, f)
52    }
53}
54
55impl AsRef<str> for PackageId {
56    #[inline(always)]
57    fn as_ref(&self) -> &str {
58        self.0.as_ref()
59    }
60}
61
62impl AsRef<Arc<str>> for PackageId {
63    #[inline(always)]
64    fn as_ref(&self) -> &Arc<str> {
65        &self.0
66    }
67}
68
69impl Deref for PackageId {
70    type Target = str;
71
72    #[inline(always)]
73    fn deref(&self) -> &Self::Target {
74        self.0.as_ref()
75    }
76}
77
78impl From<Arc<str>> for PackageId {
79    fn from(value: Arc<str>) -> Self {
80        Self(value)
81    }
82}
83
84impl From<&str> for PackageId {
85    fn from(value: &str) -> Self {
86        Self(value.to_string().into_boxed_str().into())
87    }
88}
89
90impl From<alloc::string::String> for PackageId {
91    fn from(value: alloc::string::String) -> Self {
92        Self(value.into_boxed_str().into())
93    }
94}
95
96#[cfg(feature = "arbitrary")]
97impl proptest::arbitrary::Arbitrary for PackageId {
98    type Parameters = ();
99    type Strategy = proptest::prelude::BoxedStrategy<Self>;
100    fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
101        use alloc::string::String;
102
103        use proptest::prelude::Strategy;
104
105        let chars = proptest::char::range('a', 'z');
106        proptest::collection::vec(chars, 4..32)
107            .prop_map(|chars| Self(String::from_iter(chars).into_boxed_str().into()))
108            .no_shrink()  // Pure random strings, no meaningful shrinking pattern
109            .boxed()
110    }
111}
112
113mod serialization {
114    use miden_core::serde::*;
115
116    use super::PackageId;
117
118    impl Serializable for PackageId {
119        fn write_into<W: ByteWriter>(&self, target: &mut W) {
120            // This is equivalent to String::write_into
121            target.write_usize(self.0.len());
122            target.write_bytes(self.0.as_bytes());
123        }
124    }
125
126    impl Deserializable for PackageId {
127        fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
128            alloc::string::String::read_from(source).map(Self::from)
129        }
130    }
131}