1use alloc::string::{String, ToString};
2use core::{fmt, str::FromStr};
3
4#[cfg(all(feature = "arbitrary", feature = "serde", test))]
5use miden_core::serde::{Deserializable, Serializable};
6
7#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
9#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
10#[cfg_attr(
11 all(feature = "arbitrary", feature = "serde", test),
12 miden_test_serde_macros::serde_test(binary_serde(true))
13)]
14#[repr(u8)]
15pub enum Linkage {
16 #[default]
19 Dynamic = 0,
20 Static,
26}
27
28impl Linkage {
29 pub const fn as_str(&self) -> &'static str {
31 match self {
32 Self::Dynamic => "dynamic",
33 Self::Static => "static",
34 }
35 }
36}
37
38impl fmt::Display for Linkage {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 f.write_str(self.as_str())
41 }
42}
43
44#[derive(Debug, thiserror::Error)]
46#[error("unknown linkage '{0}': expected either 'dynamic' or 'static'")]
47pub struct UnknownLinkageError(String);
48
49impl FromStr for Linkage {
50 type Err = UnknownLinkageError;
51
52 fn from_str(s: &str) -> Result<Self, Self::Err> {
53 match s {
54 "default" | "dynamic" => Ok(Self::Dynamic),
55 "static" => Ok(Self::Static),
56 other => Err(UnknownLinkageError(other.to_string())),
57 }
58 }
59}
60
61#[cfg(feature = "serde")]
62mod serialization {
63 use alloc::format;
64
65 use miden_core::serde::{
66 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
67 };
68
69 use super::Linkage;
70
71 impl serde::Serialize for Linkage {
72 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73 where
74 S: serde::Serializer,
75 {
76 if serializer.is_human_readable() {
77 self.as_str().serialize(serializer)
78 } else {
79 (*self as u8).serialize(serializer)
80 }
81 }
82 }
83
84 impl<'de> serde::Deserialize<'de> for Linkage {
85 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
86 where
87 D: serde::Deserializer<'de>,
88 {
89 if deserializer.is_human_readable() {
90 <&'de str>::deserialize(deserializer)?
91 .parse::<Linkage>()
92 .map_err(serde::de::Error::custom)
93 } else {
94 match u8::deserialize(deserializer)? {
95 0 => Ok(Self::Dynamic),
96 1 => Ok(Self::Static),
97 other => {
98 Err(serde::de::Error::custom(format!("invalid Linkage tag '{other}'")))
99 },
100 }
101 }
102 }
103 }
104
105 impl Serializable for Linkage {
106 fn write_into<W: ByteWriter>(&self, target: &mut W) {
107 target.write_u8(*self as u8);
108 }
109 }
110
111 impl Deserializable for Linkage {
112 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
113 match source.read_u8()? {
114 0 => Ok(Self::Dynamic),
115 1 => Ok(Self::Static),
116 other => Err(DeserializationError::InvalidValue(format!(
117 "unknown Linkage tag '{other}'"
118 ))),
119 }
120 }
121 }
122}