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