objectiveai_sdk/cli/command/
path_ref.rs1use std::str::FromStr;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
17pub enum Remote {
18 Github,
19 Client,
20 Mock,
21}
22
23impl Remote {
24 pub fn into_path(
28 self,
29 owner: Option<String>,
30 repository: Option<String>,
31 name: Option<String>,
32 commit: Option<String>,
33 ) -> Option<crate::RemotePathCommitOptional> {
34 match self {
35 Remote::Github => Some(crate::RemotePathCommitOptional::Github {
36 owner: owner?,
37 repository: repository?,
38 commit,
39 }),
40 Remote::Client => Some(crate::RemotePathCommitOptional::Client {
41 owner: owner?,
42 repository: repository?,
43 commit,
44 }),
45 Remote::Mock => Some(crate::RemotePathCommitOptional::Mock { name: name? }),
46 }
47 }
48
49 fn parse_keyword(s: &str) -> Result<Self, String> {
50 match s {
51 "github" => Ok(Self::Github),
52 "client" => Ok(Self::Client),
53 "mock" => Ok(Self::Mock),
54 other => Err(format!(
55 "unknown remote: {other} (expected github, client, or mock)"
56 )),
57 }
58 }
59}
60
61pub(crate) fn tokenize(s: &str) -> Result<Vec<(&str, &str)>, String> {
65 s.split(',')
66 .map(|pair| {
67 pair.split_once('=')
68 .map(|(k, v)| (k.trim(), v.trim()))
69 .ok_or_else(|| format!("expected key=value, got: {pair}"))
70 })
71 .collect()
72}
73
74impl FromStr for crate::RemotePathCommitOptional {
75 type Err = String;
76
77 fn from_str(s: &str) -> Result<Self, Self::Err> {
81 let mut remote: Option<Remote> = None;
82 let mut owner: Option<String> = None;
83 let mut repository: Option<String> = None;
84 let mut name: Option<String> = None;
85 let mut commit: Option<String> = None;
86 for (k, v) in tokenize(s)? {
87 match k {
88 "remote" => remote = Some(Remote::parse_keyword(v)?),
89 "owner" => owner = Some(v.to_string()),
90 "repository" => repository = Some(v.to_string()),
91 "name" => name = Some(v.to_string()),
92 "commit" => commit = Some(v.to_string()),
93 other => return Err(format!("unknown key: {other}")),
94 }
95 }
96 let remote = remote.ok_or_else(|| "remote is required".to_string())?;
97 remote
98 .into_path(owner, repository, name, commit)
99 .ok_or_else(|| {
100 "owner and repository are required for github/client, name for mock"
101 .to_string()
102 })
103 }
104}
105
106pub fn remote_path_to_arg_string(path: &crate::RemotePathCommitOptional) -> String {
109 match path {
110 crate::RemotePathCommitOptional::Github {
111 owner,
112 repository,
113 commit,
114 } => {
115 let mut s = format!("remote=github,owner={owner},repository={repository}");
116 if let Some(c) = commit {
117 s.push_str(&format!(",commit={c}"));
118 }
119 s
120 }
121 crate::RemotePathCommitOptional::Client {
122 owner,
123 repository,
124 commit,
125 } => {
126 let mut s = format!("remote=client,owner={owner},repository={repository}");
127 if let Some(c) = commit {
128 s.push_str(&format!(",commit={c}"));
129 }
130 s
131 }
132 crate::RemotePathCommitOptional::Mock { name } => format!("remote=mock,name={name}"),
133 }
134}