use alloc::string::{String, ToString};
use core::{fmt, str::FromStr};
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum Linkage {
#[default]
Dynamic = 0,
Static,
}
impl Linkage {
pub const fn as_str(&self) -> &'static str {
match self {
Self::Dynamic => "dynamic",
Self::Static => "static",
}
}
}
impl fmt::Display for Linkage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, thiserror::Error)]
#[error("unknown linkage '{0}': expected either 'dynamic' or 'static'")]
pub struct UnknownLinkageError(String);
impl FromStr for Linkage {
type Err = UnknownLinkageError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"default" | "dynamic" => Ok(Self::Dynamic),
"static" => Ok(Self::Static),
other => Err(UnknownLinkageError(other.to_string())),
}
}
}
#[cfg(feature = "serde")]
mod serialization {
use alloc::format;
use miden_core::serde::{
ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
};
use super::Linkage;
impl serde::Serialize for Linkage {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
self.as_str().serialize(serializer)
} else {
(*self as u8).serialize(serializer)
}
}
}
impl<'de> serde::Deserialize<'de> for Linkage {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
<&'de str>::deserialize(deserializer)?
.parse::<Linkage>()
.map_err(serde::de::Error::custom)
} else {
match u8::deserialize(deserializer)? {
0 => Ok(Self::Dynamic),
1 => Ok(Self::Static),
other => {
Err(serde::de::Error::custom(format!("invalid Linkage tag '{other}'")))
},
}
}
}
}
impl Serializable for Linkage {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write_u8(*self as u8);
}
}
impl Deserializable for Linkage {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
match source.read_u8()? {
0 => Ok(Self::Dynamic),
1 => Ok(Self::Static),
other => Err(DeserializationError::InvalidValue(format!(
"unknown Linkage tag '{other}'"
))),
}
}
}
}