wasm_pkg_common/
package.rs1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{label::Label, Error};
6
7pub use semver::Version;
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 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}
71
72#[derive(Clone, Debug)]
74pub struct PackageSpec {
75 pub package: PackageRef,
76 pub version: Option<Version>,
77}
78
79impl FromStr for PackageSpec {
80 type Err = Error;
81
82 fn from_str(s: &str) -> Result<Self, Self::Err> {
83 let (package, version) = s
84 .split_once('@')
85 .map(|(pkg, ver)| (pkg, Some(ver)))
86 .unwrap_or((s, None));
87 Ok(Self {
88 package: package.parse()?,
89 version: version.map(|ver| ver.parse()).transpose()?,
90 })
91 }
92}