wasm_pkg_common/
package.rs1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{Error, label::Label};
6
7pub use semver::{Version, VersionReq};
8
9#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
13#[serde(into = "String", try_from = "String")]
14pub struct PackageRef {
15 namespace: Label,
16 name: Label,
17}
18
19impl PackageRef {
20 pub fn new(namespace: Label, name: Label) -> Self {
22 Self { namespace, name }
23 }
24
25 pub const fn namespace(&self) -> &Label {
27 &self.namespace
28 }
29
30 pub fn name(&self) -> &Label {
32 &self.name
33 }
34}
35
36impl std::fmt::Display for PackageRef {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 write!(f, "{}:{}", self.namespace, self.name)
39 }
40}
41
42impl From<PackageRef> for String {
43 fn from(value: PackageRef) -> Self {
44 value.to_string()
45 }
46}
47
48impl TryFrom<String> for PackageRef {
49 type Error = Error;
50
51 fn try_from(mut value: String) -> Result<Self, Self::Error> {
52 let Some(colon) = value.find(':') else {
53 return Err(Error::InvalidPackageRef("missing expected ':'".into()));
54 };
55 let name = value.split_off(colon + 1);
56 value.truncate(colon);
57 Ok(Self {
58 namespace: value.parse()?,
59 name: name.parse()?,
60 })
61 }
62}
63
64impl FromStr for PackageRef {
65 type Err = Error;
66
67 fn from_str(s: &str) -> Result<Self, Self::Err> {
68 s.to_string().try_into()
69 }
70}
71impl std::fmt::Display for PackageSpec {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 if let Some(version) = &self.version {
74 write!(f, "{}@{}", self.package, version)
75 } else {
76 write!(f, "{}", self.package)
77 }
78 }
79}
80
81#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
83pub struct PackageSpec {
84 pub package: PackageRef,
85 pub version: Option<Version>,
86}
87
88impl PartialEq<str> for PackageSpec {
89 fn eq(&self, other: &str) -> bool {
90 format!("{self}") == other
92 }
93}
94
95impl FromStr for PackageSpec {
96 type Err = Error;
97
98 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 let (package, version) = s
100 .split_once('@')
101 .map(|(pkg, ver)| (pkg, Some(ver)))
102 .unwrap_or((s, None));
103 Ok(Self {
104 package: package.parse()?,
105 version: version.map(|ver| ver.parse()).transpose()?,
106 })
107 }
108}