onetaskgraph_core/
global_id.rs1use std::fmt;
7use std::str::FromStr;
8
9use onetaskgraph_plugin_api::{NativeId, SourceError, SourceName};
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
18#[serde(try_from = "String", into = "String")]
19pub struct GlobalId {
20 pub source: SourceName,
22 pub native: NativeId,
24}
25
26impl GlobalId {
27 #[must_use]
29 pub fn new(source: SourceName, native: NativeId) -> Self {
30 Self { source, native }
31 }
32}
33
34impl fmt::Display for GlobalId {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 write!(f, "{}:{}", self.source, self.native)
37 }
38}
39
40impl FromStr for GlobalId {
41 type Err = SourceError;
42
43 fn from_str(value: &str) -> Result<Self, Self::Err> {
44 let Some((source, native)) = value.split_once(':') else {
45 return Err(SourceError::Config {
46 message: format!(
47 "{value:?} is not a qualified id; write it as <source>:<id>, for example \
48 work:ENG-1"
49 ),
50 });
51 };
52 if native.is_empty() {
53 return Err(SourceError::Config {
54 message: format!("{value:?} names a source but no id; write it as <source>:<id>"),
55 });
56 }
57 Ok(Self {
58 source: SourceName::new(source)?,
59 native: NativeId::from(native),
60 })
61 }
62}
63
64impl TryFrom<String> for GlobalId {
65 type Error = SourceError;
66
67 fn try_from(value: String) -> Result<Self, Self::Error> {
68 value.parse()
69 }
70}
71
72impl From<GlobalId> for String {
73 fn from(value: GlobalId) -> Self {
74 value.to_string()
75 }
76}