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(
159 "The value '{actual}' of the 'branch' field of submodule '{submodule}' couldn't be turned into a valid fetch refspec"
160 )]
161 pub struct Error {
162 pub submodule: BString,
163 pub actual: BString,
164 pub source: gix_refspec::parse::Error,
165 }
166}
167
168pub mod update {
170 use bstr::BString;
171
172 #[derive(Debug, thiserror::Error)]
174 #[allow(missing_docs)]
175 pub enum Error {
176 #[error("The 'update' field of submodule '{submodule}' tried to set command '{actual}' to be shared")]
177 CommandForbiddenInModulesConfiguration { submodule: BString, actual: BString },
178 #[error("The 'update' field of submodule '{submodule}' was invalid: '{actual}'")]
179 Invalid { submodule: BString, actual: BString },
180 }
181}
182
183pub mod url {
185 use bstr::BString;
186
187 #[derive(Debug, thiserror::Error)]
189 #[allow(missing_docs)]
190 pub enum Error {
191 #[error("The url of submodule '{submodule}' could not be parsed")]
192 Parse {
193 submodule: BString,
194 source: gix_url::parse::Error,
195 },
196 #[error("The submodule '{submodule}' was missing its 'url' field or it was empty")]
197 Missing { submodule: BString },
198 }
199}
200
201pub mod path {
203 use bstr::BString;
204
205 #[derive(Debug, thiserror::Error)]
207 #[allow(missing_docs)]
208 pub enum Error {
209 #[error("The path '{actual}' of submodule '{submodule}' needs to be relative")]
210 Absolute { actual: BString, submodule: BString },
211 #[error("The submodule '{submodule}' was missing its 'path' field or it was empty")]
212 Missing { submodule: BString },
213 #[error("The path '{actual}' would lead outside of the repository worktree")]
214 OutsideOfWorktree { actual: BString, submodule: BString },
215 }
216}