1use crate::actor_id::{
4 actor_type_to_str, format_actor_id, parse_actor_type, split_scheme, ActorIdParseError,
5};
6use crate::generated::common::ActorType;
7
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct ParsedInstanceId {
10 pub actor_type: ActorType,
11 pub actor_path: String,
12 pub instance_path: String,
13 pub raw: String,
14}
15
16pub fn parse_instance_id(s: &str) -> Result<ParsedInstanceId, ActorIdParseError> {
17 let parts = split_scheme(s).ok_or_else(|| ActorIdParseError::MalformedScheme(s.to_owned()))?;
18 if parts.kind != "instance" {
19 return Err(ActorIdParseError::WrongKind(parts.kind.to_owned()));
20 }
21 let actor_type = parse_actor_type(parts.type_segment)
22 .ok_or_else(|| ActorIdParseError::UnknownType(parts.type_segment.to_owned()))?;
23 let split = parts.path.rfind('/').ok_or(ActorIdParseError::EmptyPath)?;
24 if split == 0 {
25 return Err(ActorIdParseError::EmptyPath);
26 }
27 let actor_path = &parts.path[..split];
28 let instance_path = &parts.path[split + 1..];
29 if actor_path.is_empty() || instance_path.is_empty() {
30 return Err(ActorIdParseError::EmptyPath);
31 }
32 Ok(ParsedInstanceId {
33 actor_type,
34 actor_path: actor_path.to_owned(),
35 instance_path: instance_path.to_owned(),
36 raw: s.to_owned(),
37 })
38}
39
40pub fn format_instance_id(
41 actor_type: &ActorType,
42 actor_path: &str,
43 instance_path: &str,
44) -> Result<String, ActorIdParseError> {
45 if actor_path.is_empty() || instance_path.is_empty() {
46 return Err(ActorIdParseError::EmptyPath);
47 }
48 Ok(format!(
49 "tf:instance:{}:{}/{}",
50 actor_type_to_str(actor_type),
51 actor_path,
52 instance_path
53 ))
54}
55
56pub fn to_actor_id(instance_id: &str) -> Result<String, ActorIdParseError> {
57 let parsed = parse_instance_id(instance_id)?;
58 format_actor_id(&parsed.actor_type, &parsed.actor_path)
59}