1use std::str::{FromStr, Split};
2
3use serde::{Deserialize, Serialize};
4
5use crate::error::Error;
6
7use crate::resource::{
8 ArtifactBundleKey, ArtifactKey, ArtifactKind, Path,
9 ResourceAddress, ResourceAddressPart, ResourceKey, ResourceType,
10};
11use starlane_resources::ResourcePath;
12
13
14#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
15pub struct ArtifactBundle {
16 pub domain: String,
17 pub space: String,
18 pub sub_space: String,
19 pub bundle: String,
20 pub version: String,
21}
22
23impl ArtifactBundle {
24 pub fn more(string: &str) -> Result<(Self, Split<&str>), Error> {
25 let mut parts = string.split(":");
26
27 Ok((
28 ArtifactBundle {
29 domain: parts.next().ok_or("hyper")?.to_string(),
30 space: parts.next().ok_or("space")?.to_string(),
31 sub_space: parts.next().ok_or("sub_space")?.to_string(),
32 bundle: parts.next().ok_or("bundle")?.to_string(),
33 version: parts.next().ok_or("version")?.to_string(),
34 },
35 parts,
36 ))
37 }
38}
39
40impl FromStr for ArtifactBundle {
41 type Err = Error;
42
43 fn from_str(string: &str) -> Result<Self, Self::Err> {
44 let (bundle, _) = ArtifactBundle::more(string)?;
45 Ok(bundle)
46 }
47}
48
49impl ToString for ArtifactBundle {
50 fn to_string(&self) -> String {
51 let mut rtn = String::new();
52 rtn.push_str(self.domain.as_str());
53 rtn.push_str(":");
54 rtn.push_str(self.space.as_str());
55 rtn.push_str(":");
56 rtn.push_str(self.sub_space.to_string().as_str());
57 rtn.push_str(":");
58 rtn.push_str(self.bundle.to_string().as_str());
59 rtn.push_str(":");
60 rtn.push_str(self.version.to_string().as_str());
61 return rtn;
62 }
63}
64
65#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
66pub struct ArtifactLocation {
67 pub bundle: ArtifactBundle,
68 pub path: String,
69}
70
71impl FromStr for ArtifactLocation {
72 type Err = Error;
73
74 fn from_str(string: &str) -> Result<Self, Self::Err> {
75 let (bundle, mut parts) = ArtifactBundle::more(string)?;
76 let path = parts.next().ok_or("path")?.to_string();
77 Ok(ArtifactLocation {
78 bundle: bundle,
79 path: path,
80 })
81 }
82}
83
84impl ToString for ArtifactLocation {
85 fn to_string(&self) -> String {
86 let mut rtn = String::new();
87 rtn.push_str(self.bundle.to_string().as_str());
88 rtn.push_str(":");
89 rtn.push_str(self.path.to_string().as_str());
90 return rtn;
91 }
92}
93
94#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
95pub struct DomainName {
96 pub domain: String,
97}
98
99impl DomainName {
100 pub fn more(string: &str) -> Result<(Self, Split<&str>), Error> {
101 let mut parts = string.split(":");
102
103 Ok((
104 DomainName {
105 domain: parts.next().ok_or("hyper")?.to_string(),
106 },
107 parts,
108 ))
109 }
110
111 pub fn from(string: &str) -> Result<Self, Error> {
112 let (hyper, _) = DomainName::more(string)?;
113 Ok(hyper)
114 }
115
116 pub fn to(&self) -> String {
117 let mut rtn = String::new();
118 rtn.push_str(self.domain.as_str());
119 return rtn;
120 }
121}
122
123#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
124pub struct SpaceName {
125 pub hyper: DomainName,
126 pub space: String,
127}
128
129impl SpaceName {
130 pub fn more(string: &str) -> Result<(Self, Split<&str>), Error> {
131 let (hyper, mut parts) = DomainName::more(string)?;
132
133 Ok((
134 SpaceName {
135 hyper: hyper,
136 space: parts.next().ok_or("space")?.to_string(),
137 },
138 parts,
139 ))
140 }
141
142 pub fn from(string: &str) -> Result<Self, Error> {
143 let (space, _) = SpaceName::more(string)?;
144 Ok(space)
145 }
146
147 pub fn to(&self) -> String {
148 let mut rtn = String::new();
149 rtn.push_str(self.hyper.to().as_str());
150 rtn.push_str(":");
151 rtn.push_str(self.space.as_str());
152 return rtn;
153 }
154}
155
156#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
157pub struct SubSpaceName {
158 pub space: SpaceName,
159 pub sub_space: String,
160}
161
162impl SubSpaceName {
163 pub fn more(string: &str) -> Result<(Self, Split<&str>), Error> {
164 let (space, mut parts) = SpaceName::more(string)?;
165
166 Ok((
167 SubSpaceName {
168 space: space,
169 sub_space: parts.next().ok_or("sub_space")?.to_string(),
170 },
171 parts,
172 ))
173 }
174
175 pub fn from(string: &str) -> Result<Self, Error> {
176 let (sub_space, _) = SubSpaceName::more(string)?;
177 Ok(sub_space)
178 }
179
180 pub fn to(&self) -> String {
181 let mut rtn = String::new();
182 rtn.push_str(self.space.to().as_str());
183 rtn.push_str(":");
184 rtn.push_str(self.sub_space.as_str());
185 return rtn;
186 }
187}
188
189
190#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
191pub struct ArtifactRef {
192 pub path: ResourcePath,
193 pub kind: ArtifactKind,
194}
195
196impl ArtifactRef {
197 pub fn new(path: ResourcePath, kind: ArtifactKind) -> Self {
198 Self {
199 path,
200 kind,
201 }
202 }
203
204 pub fn trailing_path(&self) -> Result<Path,Error> {
205 Ok(Path::from_str(self.path.segments.last().as_ref().ok_or("expected one ResourcePath segment")?.as_str())?)
206 }
207}