1use bstr::{BStr, BString, ByteSlice};
2
3#[derive(Default, Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
5pub enum Ignore {
6 All,
8 Dirty,
11 Untracked,
14 #[default]
17 None,
18}
19
20impl TryFrom<&BStr> for Ignore {
21 type Error = ();
22
23 fn try_from(value: &BStr) -> Result<Self, Self::Error> {
24 Ok(match value.as_bytes() {
25 b"all" => Ignore::All,
26 b"dirty" => Ignore::Dirty,
27 b"untracked" => Ignore::Untracked,
28 b"none" => Ignore::None,
29 _ => return Err(()),
30 })
31 }
32}
33
34#[derive(Default, Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
41pub enum FetchRecurse {
42 #[default]
44 OnDemand,
45 Always,
50 Never,
52}
53
54impl FetchRecurse {
55 pub fn new(boolean: Result<bool, gix_config::value::Error>) -> Result<Self, BString> {
59 Ok(match boolean {
60 Ok(value) => {
61 if value {
62 FetchRecurse::Always
63 } else {
64 FetchRecurse::Never
65 }
66 }
67 Err(err) => {
68 if err.input != "on-demand" {
69 return Err(err.input);
70 }
71 FetchRecurse::OnDemand
72 }
73 })
74 }
75}
76
77#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
79pub enum Branch {
80 CurrentInSuperproject,
82 Name(BString),
84}
85
86impl Default for Branch {
87 fn default() -> Self {
88 Branch::Name("HEAD".into())
89 }
90}
91
92impl TryFrom<&BStr> for Branch {
93 type Error = gix_refspec::parse::Error;
94
95 fn try_from(value: &BStr) -> Result<Self, Self::Error> {
96 if value == "." {
97 return Ok(Branch::CurrentInSuperproject);
98 }
99
100 gix_refspec::parse(value, gix_refspec::parse::Operation::Fetch)
101 .map(|spec| Branch::Name(spec.source().expect("no object").to_owned()))
102 }
103}
104
105#[derive(Default, Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
108pub enum Update {
109 #[default]
111 Checkout,
112 Rebase,
114 Merge,
116 Command(BString),
122 None,
124}
125
126impl TryFrom<&BStr> for Update {
127 type Error = ();
128
129 fn try_from(value: &BStr) -> Result<Self, Self::Error> {
130 Ok(match value.as_bstr().as_bytes() {
131 b"checkout" => Update::Checkout,
132 b"rebase" => Update::Rebase,
133 b"merge" => Update::Merge,
134 b"none" => Update::None,
135 command if command.first() == Some(&b'!') => Update::Command(command[1..].to_owned().into()),
136 _ => return Err(()),
137 })
138 }
139}
140
141#[derive(Debug, thiserror::Error)]
143#[allow(missing_docs)]
144#[error("The '{field}' field of submodule '{submodule}' was invalid: '{actual}'")]
145pub struct Error {
146 pub field: &'static str,
147 pub submodule: BString,
148 pub actual: BString,
149}
150
151pub mod branch {
153 use bstr::BString;
154
155 #[derive(Debug, thiserror::Error)]
157 #[allow(missing_docs)]
158 #[error("The value '{actual}' of the 'branch' field of submodule '{submodule}' couldn't be turned into a valid fetch refspec")]
159 pub struct Error {
160 pub submodule: BString,
161 pub actual: BString,
162 pub source: gix_refspec::parse::Error,
163 }
164}
165
166pub mod update {
168 use bstr::BString;
169
170 #[derive(Debug, thiserror::Error)]
172 #[allow(missing_docs)]
173 pub enum Error {
174 #[error("The 'update' field of submodule '{submodule}' tried to set command '{actual}' to be shared")]
175 CommandForbiddenInModulesConfiguration { submodule: BString, actual: BString },
176 #[error("The 'update' field of submodule '{submodule}' was invalid: '{actual}'")]
177 Invalid { submodule: BString, actual: BString },
178 }
179}
180
181pub mod url {
183 use bstr::BString;
184
185 #[derive(Debug, thiserror::Error)]
187 #[allow(missing_docs)]
188 pub enum Error {
189 #[error("The url of submodule '{submodule}' could not be parsed")]
190 Parse {
191 submodule: BString,
192 source: gix_url::parse::Error,
193 },
194 #[error("The submodule '{submodule}' was missing its 'url' field or it was empty")]
195 Missing { submodule: BString },
196 }
197}
198
199pub mod path {
201 use bstr::BString;
202
203 #[derive(Debug, thiserror::Error)]
205 #[allow(missing_docs)]
206 pub enum Error {
207 #[error("The path '{actual}' of submodule '{submodule}' needs to be relative")]
208 Absolute { actual: BString, submodule: BString },
209 #[error("The submodule '{submodule}' was missing its 'path' field or it was empty")]
210 Missing { submodule: BString },
211 #[error("The path '{actual}' would lead outside of the repository worktree")]
212 OutsideOfWorktree { actual: BString, submodule: BString },
213 }
214}