wasmer_config/package/
package_ident.rs1use std::str::FromStr;
2
3use super::{NamedPackageIdent, PackageHash, PackageId, PackageParseError};
4
5#[derive(PartialEq, Eq, Clone, Debug, Hash)]
6pub enum PackageIdent {
7 Named(NamedPackageIdent),
8 Hash(PackageHash),
9}
10
11impl PackageIdent {
12 pub fn as_named(&self) -> Option<&NamedPackageIdent> {
13 if let Self::Named(v) = self {
14 Some(v)
15 } else {
16 None
17 }
18 }
19
20 pub fn as_hash(&self) -> Option<&PackageHash> {
21 if let Self::Hash(v) = self {
22 Some(v)
23 } else {
24 None
25 }
26 }
27
28 pub fn matches_id(&self, id: &PackageId) -> bool {
32 match (self, id) {
33 (Self::Named(a), PackageId::Named(b)) => a.matches_id(b),
34 (Self::Hash(a), PackageId::Hash(b)) => a == b,
35 _ => false,
36 }
37 }
38}
39
40impl From<NamedPackageIdent> for PackageIdent {
41 fn from(value: NamedPackageIdent) -> Self {
42 Self::Named(value)
43 }
44}
45
46impl From<PackageHash> for PackageIdent {
47 fn from(value: PackageHash) -> Self {
48 Self::Hash(value)
49 }
50}
51
52impl std::str::FromStr for PackageIdent {
53 type Err = PackageParseError;
54
55 fn from_str(s: &str) -> Result<Self, Self::Err> {
56 if let Ok(hash) = PackageHash::from_str(s) {
57 Ok(Self::Hash(hash))
58 } else {
59 match NamedPackageIdent::from_str(s) {
60 Ok(named) => Ok(Self::Named(named)),
61 _ => Err(PackageParseError::new(
62 s,
63 "invalid package ident: expected a hash or a valid named package identifier",
64 )),
65 }
66 }
67 }
68}
69
70impl std::fmt::Display for PackageIdent {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 match self {
73 Self::Named(n) => n.fmt(f),
74 Self::Hash(h) => h.fmt(f),
75 }
76 }
77}
78
79impl serde::Serialize for PackageIdent {
80 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81 where
82 S: serde::ser::Serializer,
83 {
84 self.to_string().serialize(serializer)
85 }
86}
87
88impl<'de> serde::Deserialize<'de> for PackageIdent {
89 fn deserialize<D>(deserializer: D) -> Result<PackageIdent, D::Error>
90 where
91 D: serde::de::Deserializer<'de>,
92 {
93 let s = String::deserialize(deserializer)?;
94 Self::from_str(&s).map_err(serde::de::Error::custom)
95 }
96}
97
98impl schemars::JsonSchema for PackageIdent {
99 fn schema_name() -> String {
100 "PackageIdent".to_string()
101 }
102
103 fn json_schema(r#gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
104 String::json_schema(r#gen)
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn test_package_ident_matches_id() {
114 assert!(
115 PackageIdent::from_str("ns/pkg")
116 .unwrap()
117 .matches_id(&PackageId::new_named("ns/pkg", "1.0.0".parse().unwrap()))
118 );
119
120 assert!(
121 PackageIdent::from_str("ns/pkg@2")
122 .unwrap()
123 .matches_id(&PackageId::new_named("ns/pkg", "2.3.7".parse().unwrap()))
124 );
125
126 assert!(
127 !PackageIdent::from_str("ns/pkg@3")
128 .unwrap()
129 .matches_id(&PackageId::new_named("ns/pkg", "2.3.7".parse().unwrap()))
130 );
131 }
132}