1use std::{error::Error, fmt::Display, str::FromStr};
3
4#[derive(Clone, Debug)]
6pub struct CVarOverride(pub(crate) String, pub(crate) toml_edit::Value);
7
8#[derive(Debug)]
10#[non_exhaustive]
11pub enum CVarOverrideParseError {
12 InvalidPath,
14 InvalidToml,
16 DoesntLookLikeAnOverride,
18}
19
20impl Error for CVarOverrideParseError {}
21
22impl Display for CVarOverrideParseError {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 CVarOverrideParseError::InvalidPath => write!(
26 f,
27 "Not a valid override, a CVar override must have a CVar path (a.b.c) on the left."
28 ),
29 CVarOverrideParseError::InvalidToml => write!(
30 f,
31 "Not a valid override, a CVar override must have TOML on the right."
32 ),
33 CVarOverrideParseError::DoesntLookLikeAnOverride => write!(
34 f,
35 "Not a valid override, a CVar override must be of form `left=right`"
36 ),
37 }
38 }
39}
40
41impl TryFrom<&str> for CVarOverride {
42 type Error = CVarOverrideParseError;
43
44 fn try_from(value: &str) -> Result<Self, Self::Error> {
45 let (left, right) = value
46 .split_once('=')
47 .ok_or(CVarOverrideParseError::DoesntLookLikeAnOverride)?;
48
49 let value =
50 toml_edit::Value::from_str(right).map_err(|_| CVarOverrideParseError::InvalidToml)?;
51
52 Ok(CVarOverride(left.to_owned(), value))
53 }
54}
55
56impl FromStr for CVarOverride {
57 type Err = CVarOverrideParseError;
58
59 fn from_str(s: &str) -> Result<Self, Self::Err> {
60 Self::try_from(s)
61 }
62}