Skip to main content

miden_mast_package/package/
kind.rs

1#[cfg(feature = "serde")]
2use alloc::{
3    format,
4    string::{String, ToString},
5};
6use core::fmt;
7
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as DeError};
10
11// PACKAGE KIND
12// ================================================================================================
13
14/// The kind of project that produced this package.
15///
16/// This helps consumers of the package understand how to use it (e.g., as an account component,
17/// a note script, a transaction script, etc.).
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
20#[cfg_attr(all(feature = "arbitrary", test), miden_test_serde_macros::serde_test)]
21#[non_exhaustive]
22#[repr(u8)]
23pub enum PackageKind {
24    /// A generic code library package.
25    Library = 0,
26    /// An executable program package.
27    Executable = 1,
28    /// An account component package.
29    AccountComponent = 2,
30    /// A note script package.
31    NoteScript = 3,
32    /// A transaction script package.
33    TransactionScript = 4,
34}
35
36impl PackageKind {
37    /// Returns the string representation of this package kind.
38    pub const fn as_str(&self) -> &'static str {
39        match self {
40            Self::Library => "library",
41            Self::Executable => "executable",
42            Self::AccountComponent => "account-component",
43            Self::NoteScript => "note-script",
44            Self::TransactionScript => "transaction-script",
45        }
46    }
47}
48
49// CONVERSIONS
50// ================================================================================================
51
52impl TryFrom<u8> for PackageKind {
53    type Error = InvalidPackageKindError;
54
55    fn try_from(value: u8) -> Result<Self, Self::Error> {
56        match value {
57            0 => Ok(Self::Library),
58            1 => Ok(Self::Executable),
59            2 => Ok(Self::AccountComponent),
60            3 => Ok(Self::NoteScript),
61            4 => Ok(Self::TransactionScript),
62            _ => Err(InvalidPackageKindError(value)),
63        }
64    }
65}
66
67impl From<PackageKind> for u8 {
68    fn from(kind: PackageKind) -> Self {
69        kind as u8
70    }
71}
72
73impl fmt::Display for PackageKind {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        f.write_str(self.as_str())
76    }
77}
78
79// SERIALIZATION
80// ================================================================================================
81
82#[cfg(feature = "serde")]
83impl Serialize for PackageKind {
84    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
85    where
86        S: Serializer,
87    {
88        if serializer.is_human_readable() {
89            serializer.serialize_str(self.as_str())
90        } else {
91            serializer.serialize_u8(*self as u8)
92        }
93    }
94}
95
96#[cfg(feature = "serde")]
97impl<'de> Deserialize<'de> for PackageKind {
98    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99    where
100        D: Deserializer<'de>,
101    {
102        if deserializer.is_human_readable() {
103            let s = String::deserialize(deserializer)?;
104            match s.as_str() {
105                "library" => Ok(Self::Library),
106                "executable" => Ok(Self::Executable),
107                "account-component" => Ok(Self::AccountComponent),
108                "note-script" => Ok(Self::NoteScript),
109                "transaction-script" => Ok(Self::TransactionScript),
110                _ => Err(DeError::custom(format!("invalid package kind: {}", s))),
111            }
112        } else {
113            let tag = u8::deserialize(deserializer)?;
114            Self::try_from(tag).map_err(|e| DeError::custom(e.to_string()))
115        }
116    }
117}
118
119// ERROR
120// ================================================================================================
121
122/// Error returned when trying to convert an invalid u8 to a [PackageKind].
123#[derive(Debug, Clone, Copy, PartialEq, Eq)]
124pub struct InvalidPackageKindError(pub u8);
125
126impl fmt::Display for InvalidPackageKindError {
127    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128        write!(f, "invalid package kind tag: {}", self.0)
129    }
130}