1
0
mirror of https://github.com/Llewellynvdm/starship.git synced 2025-01-24 15:48:34 +00:00

refactor: replace module_config_derive with serde (#3786)

* refactor: replace module_config_derive with serde

Changes include:
* Removing `starship_module_config_derive` and replacing it with `serde::Deserialize`
* Removing `RootModuleConfig::load_config`. While potentially useful, it was only used in tests. And it would require something like `serde::DeserializeSeed` which is not derived by serde.
* Merging `RootModuleConfig` into `ModuleConfig`
* Implementing a `ValueDeserializer` that holds a reference to a `toml::Value` in `serde_utils.rs`
* Deserialization errors (invalid type) are now logged and include the current key and the struct names
* Unknown keys are now considered an error. "Did you mean?"-messages are still possible

* fix typo

Co-authored-by: Matan Kushner <hello@matchai.dev>

Co-authored-by: Matan Kushner <hello@matchai.dev>
This commit is contained in:
David Knaack 2022-03-26 10:42:19 +01:00 committed by GitHub
parent 0fb4219690
commit 2d4b183fce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
159 changed files with 891 additions and 1011 deletions

View File

@ -53,7 +53,7 @@ pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
To run a external command (e.g. to get the version of a tool) and to allow for mocking use the `context.exec_cmd` function. Here's a quick example: To run a external command (e.g. to get the version of a tool) and to allow for mocking use the `context.exec_cmd` function. Here's a quick example:
```rust ```rust
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::php::PhpConfig; use crate::configs::php::PhpConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;
@ -163,7 +163,7 @@ Unit tests are written using the built-in Rust testing library in the same file
All tests that test the rendered output of a module should use `ModuleRenderer`. For Example: All tests that test the rendered output of a module should use `ModuleRenderer`. For Example:
```rust ```rust
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::php::PhpConfig; use crate::configs::php::PhpConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

10
Cargo.lock generated
View File

@ -1583,7 +1583,6 @@ dependencies = [
"shadow-rs", "shadow-rs",
"shell-words", "shell-words",
"starship-battery", "starship-battery",
"starship_module_config_derive",
"strsim", "strsim",
"sys-info", "sys-info",
"tempfile", "tempfile",
@ -1617,15 +1616,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "starship_module_config_derive"
version = "0.2.1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "static_assertions" name = "static_assertions"
version = "1.1.0" version = "1.1.0"

View File

@ -65,7 +65,6 @@ shadow-rs = "0.11.0"
# battery is optional (on by default) because the crate doesn't currently build for Termux # battery is optional (on by default) because the crate doesn't currently build for Termux
# see: https://github.com/svartalf/rust-battery/issues/33 # see: https://github.com/svartalf/rust-battery/issues/33
starship-battery = { version = "0.7.9", optional = true } starship-battery = { version = "0.7.9", optional = true }
starship_module_config_derive = { version = "0.2.1", path = "starship_module_config_derive" }
strsim = "0.10.0" strsim = "0.10.0"
sys-info = "0.9.1" sys-info = "0.9.1"
terminal_size = "0.1.17" terminal_size = "0.1.17"

View File

@ -1,199 +1,59 @@
use crate::serde_utils::ValueDeserializer;
use crate::utils; use crate::utils;
use ansi_term::{Color, Style}; use ansi_term::Color;
use indexmap::IndexMap; use serde::{
use serde::Serialize; de::value::Error as ValueError, de::Error as SerdeError, Deserialize, Deserializer, Serialize,
};
use std::borrow::Cow;
use std::clone::Clone; use std::clone::Clone;
use std::collections::HashMap;
use std::io::ErrorKind; use std::io::ErrorKind;
use std::marker::Sized;
use std::env; use std::env;
use toml::Value; use toml::Value;
/// Root config of a module. /// Root config of a module.
pub trait RootModuleConfig<'a> pub trait ModuleConfig<'a, E>
where where
Self: ModuleConfig<'a> + Default, Self: Default,
{ E: SerdeError,
/// Load root module config from given Value and fill unset variables with default
/// values.
fn load(config: &'a Value) -> Self {
let mut out = Self::default();
out.load_config(config);
out
}
/// Helper function that will call RootModuleConfig::load(config) if config is Some,
/// or RootModuleConfig::new() if config is None.
fn try_load(config: Option<&'a Value>) -> Self {
if let Some(config) = config {
Self::load(config)
} else {
Self::default()
}
}
}
impl<'a, T: ModuleConfig<'a> + Default> RootModuleConfig<'a> for T {}
/// Parsable config.
pub trait ModuleConfig<'a>
where
Self: Sized + Clone,
{ {
/// Construct a `ModuleConfig` from a toml value. /// Construct a `ModuleConfig` from a toml value.
fn from_config(_config: &'a Value) -> Option<Self> { fn from_config(config: &'a Value) -> Result<Self, E>;
None
}
/// Merge `self` with config from a toml table. /// Loads the TOML value into the config.
fn load_config(&mut self, config: &'a Value) { /// Missing values are set to their default values.
if let Some(value) = Self::from_config(config) { /// On error, logs an error message.
let _ = std::mem::replace(self, value); fn load(config: &'a Value) -> Self {
} match Self::from_config(config) {
} Ok(config) => config,
} Err(e) => {
log::warn!("Failed to load config value: {}", e);
// TODO: Add logging to default implementations Self::default()
impl<'a> ModuleConfig<'a> for &'a str {
fn from_config(config: &'a Value) -> Option<Self> {
config.as_str()
}
}
impl<'a> ModuleConfig<'a> for String {
fn from_config(config: &'a Value) -> Option<Self> {
config.as_str().map(std::borrow::ToOwned::to_owned)
}
}
impl<'a> ModuleConfig<'a> for Style {
fn from_config(config: &Value) -> Option<Self> {
parse_style_string(config.as_str()?)
}
}
impl<'a> ModuleConfig<'a> for bool {
fn from_config(config: &Value) -> Option<Self> {
config.as_bool()
}
}
impl<'a> ModuleConfig<'a> for i64 {
fn from_config(config: &Value) -> Option<Self> {
config.as_integer()
}
}
impl<'a> ModuleConfig<'a> for u64 {
fn from_config(config: &Value) -> Option<Self> {
match config {
Value::Integer(value) => {
// Converting i64 to u64
if *value > 0 {
Some(*value as Self)
} else {
None
}
} }
Value::String(value) => value.parse::<Self>().ok(),
_ => None,
} }
} }
}
impl<'a> ModuleConfig<'a> for f64 { /// Helper function that will call ModuleConfig::from_config(config) if config is Some,
fn from_config(config: &Value) -> Option<Self> { /// or ModuleConfig::default() if config is None.
config.as_float() fn try_load(config: Option<&'a Value>) -> Self {
config.map(Self::load).unwrap_or_default()
} }
} }
impl<'a> ModuleConfig<'a> for u32 { impl<'a, T: Deserialize<'a> + Default> ModuleConfig<'a, ValueError> for T {
fn from_config(config: &Value) -> Option<Self> { /// Create ValueDeserializer wrapper and use it to call Deserialize::deserialize on it.
match config { fn from_config(config: &'a Value) -> Result<Self, ValueError> {
Value::Integer(value) => { let deserializer = ValueDeserializer::new(config);
// Converting i64 to u32 T::deserialize(deserializer)
if *value > 0 && *value <= u32::MAX.into() {
Some(*value as Self)
} else {
None
}
}
Value::String(value) => value.parse::<Self>().ok(),
_ => None,
}
} }
} }
impl<'a> ModuleConfig<'a> for usize { #[derive(Clone, Deserialize, Serialize)]
fn from_config(config: &Value) -> Option<Self> { #[serde(untagged)]
match config { pub enum Either<A, B> {
Value::Integer(value) => { First(A),
if *value > 0 { Second(B),
Some(*value as Self)
} else {
None
}
}
Value::String(value) => value.parse::<Self>().ok(),
_ => None,
}
}
}
impl<'a, T> ModuleConfig<'a> for Vec<T>
where
T: ModuleConfig<'a>,
{
fn from_config(config: &'a Value) -> Option<Self> {
config
.as_array()?
.iter()
.map(|value| T::from_config(value))
.collect()
}
}
impl<'a, T, S: ::std::hash::BuildHasher + Default> ModuleConfig<'a> for HashMap<String, T, S>
where
T: ModuleConfig<'a>,
S: Clone,
{
fn from_config(config: &'a Value) -> Option<Self> {
let mut hm = Self::default();
for (x, y) in config.as_table()? {
hm.insert(x.clone(), T::from_config(y)?);
}
Some(hm)
}
}
impl<'a, T, S: ::std::hash::BuildHasher + Default> ModuleConfig<'a> for IndexMap<String, T, S>
where
T: ModuleConfig<'a>,
S: Clone,
{
fn from_config(config: &'a Value) -> Option<Self> {
let mut im = Self::default();
for (x, y) in config.as_table()? {
im.insert(x.clone(), T::from_config(y)?);
}
Some(im)
}
}
impl<'a, T> ModuleConfig<'a> for Option<T>
where
T: ModuleConfig<'a> + Sized,
{
fn from_config(config: &'a Value) -> Option<Self> {
Some(T::from_config(config))
}
} }
/// A wrapper around `Vec<T>` that implements `ModuleConfig`, and either /// A wrapper around `Vec<T>` that implements `ModuleConfig`, and either
@ -201,22 +61,19 @@ where
#[derive(Clone, Default, Serialize)] #[derive(Clone, Default, Serialize)]
pub struct VecOr<T>(pub Vec<T>); pub struct VecOr<T>(pub Vec<T>);
impl<'a, T> ModuleConfig<'a> for VecOr<T> impl<'de, T> Deserialize<'de> for VecOr<T>
where where
T: ModuleConfig<'a> + Sized, T: Deserialize<'de>,
{ {
fn from_config(config: &'a Value) -> Option<Self> { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
if let Some(item) = T::from_config(config) { where
return Some(Self(vec![item])); D: Deserializer<'de>,
{
let either = Either::<Vec<T>, T>::deserialize(deserializer)?;
match either {
Either::First(v) => Ok(VecOr(v)),
Either::Second(s) => Ok(VecOr(vec![s])),
} }
let vec = config
.as_array()?
.iter()
.map(|value| T::from_config(value))
.collect::<Option<Vec<T>>>()?;
Some(Self(vec))
} }
} }
@ -374,6 +231,16 @@ impl StarshipConfig {
} }
} }
/// Deserialize a style string in the starship format with serde
pub fn deserialize_style<'de, D>(de: D) -> Result<ansi_term::Style, D::Error>
where
D: Deserializer<'de>,
{
Cow::<'_, str>::deserialize(de).and_then(|s| {
parse_style_string(s.as_ref()).ok_or_else(|| D::Error::custom("Invalid style string"))
})
}
/** Parse a style string which represents an ansi style. Valid tokens in the style /** Parse a style string which represents an ansi style. Valid tokens in the style
string include the following: string include the following:
- 'fg:<color>' (specifies that the color read should be a foreground color) - 'fg:<color>' (specifies that the color read should be a foreground color)
@ -501,11 +368,24 @@ fn parse_color_string(color_string: &str) -> Option<ansi_term::Color> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use starship_module_config_derive::ModuleConfig; use ansi_term::Style;
// Small wrapper to allow deserializing Style without a struct with #[serde(deserialize_with=)]
#[derive(Default, Clone, Debug, PartialEq)]
struct StyleWrapper(Style);
impl<'de> Deserialize<'de> for StyleWrapper {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserialize_style(deserializer).map(Self)
}
}
#[test] #[test]
fn test_load_config() { fn test_load_config() {
#[derive(Clone, Default, ModuleConfig)] #[derive(Clone, Default, Deserialize)]
struct TestConfig<'a> { struct TestConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub disabled: bool, pub disabled: bool,
@ -517,12 +397,7 @@ mod tests {
disabled = true disabled = true
some_array = ["A"] some_array = ["A"]
}; };
let mut rust_config = TestConfig { let rust_config = TestConfig::from_config(&config).unwrap();
symbol: "S ",
disabled: false,
some_array: vec!["A", "B", "C"],
};
rust_config.load_config(&config);
assert_eq!(rust_config.symbol, "T "); assert_eq!(rust_config.symbol, "T ");
assert!(rust_config.disabled); assert!(rust_config.disabled);
@ -531,15 +406,20 @@ mod tests {
#[test] #[test]
fn test_load_nested_config() { fn test_load_nested_config() {
#[derive(Clone, Default, ModuleConfig)] #[derive(Clone, Default, Deserialize)]
#[serde(default)]
struct TestConfig<'a> { struct TestConfig<'a> {
#[serde(borrow)]
pub untracked: SegmentDisplayConfig<'a>, pub untracked: SegmentDisplayConfig<'a>,
#[serde(borrow)]
pub modified: SegmentDisplayConfig<'a>, pub modified: SegmentDisplayConfig<'a>,
} }
#[derive(PartialEq, Debug, Clone, Default, ModuleConfig)] #[derive(PartialEq, Debug, Clone, Default, Deserialize)]
#[serde(default)]
struct SegmentDisplayConfig<'a> { struct SegmentDisplayConfig<'a> {
pub value: &'a str, pub value: &'a str,
#[serde(deserialize_with = "deserialize_style")]
pub style: Style, pub style: Style,
} }
@ -548,23 +428,13 @@ mod tests {
modified = { value = "", style = "red" } modified = { value = "", style = "red" }
}; };
let mut git_status_config = TestConfig { let git_status_config = TestConfig::from_config(&config).unwrap();
untracked: SegmentDisplayConfig {
value: "?",
style: Color::Red.bold(),
},
modified: SegmentDisplayConfig {
value: "!",
style: Color::Red.bold(),
},
};
git_status_config.load_config(&config);
assert_eq!( assert_eq!(
git_status_config.untracked, git_status_config.untracked,
SegmentDisplayConfig { SegmentDisplayConfig {
value: "x", value: "x",
style: Color::Red.bold(), style: Style::default(),
} }
); );
assert_eq!( assert_eq!(
@ -578,7 +448,8 @@ mod tests {
#[test] #[test]
fn test_load_optional_config() { fn test_load_optional_config() {
#[derive(Clone, Default, ModuleConfig)] #[derive(Clone, Default, Deserialize)]
#[serde(default)]
struct TestConfig<'a> { struct TestConfig<'a> {
pub optional: Option<&'a str>, pub optional: Option<&'a str>,
pub hidden: Option<&'a str>, pub hidden: Option<&'a str>,
@ -587,11 +458,7 @@ mod tests {
let config = toml::toml! { let config = toml::toml! {
optional = "test" optional = "test"
}; };
let mut rust_config = TestConfig { let rust_config = TestConfig::from_config(&config).unwrap();
optional: None,
hidden: None,
};
rust_config.load_config(&config);
assert_eq!(rust_config.optional, Some("test")); assert_eq!(rust_config.optional, Some("test"));
assert_eq!(rust_config.hidden, None); assert_eq!(rust_config.hidden, None);
@ -599,7 +466,8 @@ mod tests {
#[test] #[test]
fn test_load_enum_config() { fn test_load_enum_config() {
#[derive(Clone, Default, ModuleConfig)] #[derive(Clone, Default, Deserialize)]
#[serde(default)]
struct TestConfig { struct TestConfig {
pub switch_a: Switch, pub switch_a: Switch,
pub switch_b: Switch, pub switch_b: Switch,
@ -612,19 +480,22 @@ mod tests {
Off, Off,
} }
impl Default for Switch { impl<'de> Deserialize<'de> for Switch {
fn default() -> Self { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
Self::Off where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
match s.to_ascii_lowercase().as_str() {
"on" => Ok(Switch::On),
_ => Ok(Switch::Off),
}
} }
} }
impl<'a> ModuleConfig<'a> for Switch { impl Default for Switch {
fn from_config(config: &'a Value) -> Option<Self> { fn default() -> Self {
match config.as_str()? { Self::Off
"on" => Some(Self::On),
"off" => Some(Self::Off),
_ => None,
}
} }
} }
@ -632,12 +503,7 @@ mod tests {
switch_a = "on" switch_a = "on"
switch_b = "any" switch_b = "any"
}; };
let mut rust_config = TestConfig { let rust_config = TestConfig::from_config(&config).unwrap();
switch_a: Switch::Off,
switch_b: Switch::Off,
switch_c: Switch::Off,
};
rust_config.load_config(&config);
assert_eq!(rust_config.switch_a, Switch::On); assert_eq!(rust_config.switch_a, Switch::On);
assert_eq!(rust_config.switch_b, Switch::Off); assert_eq!(rust_config.switch_b, Switch::Off);
@ -665,23 +531,26 @@ mod tests {
#[test] #[test]
fn test_from_style() { fn test_from_style() {
let config = Value::from("red bold"); let config = Value::from("red bold");
assert_eq!(<Style>::from_config(&config).unwrap(), Color::Red.bold()); assert_eq!(
<StyleWrapper>::from_config(&config).unwrap().0,
Color::Red.bold()
);
} }
#[test] #[test]
fn test_from_hex_color_style() { fn test_from_hex_color_style() {
let config = Value::from("#00000"); let config = Value::from("#00000");
assert_eq!(<Style>::from_config(&config), None); assert!(<StyleWrapper>::from_config(&config).is_err());
let config = Value::from("#0000000"); let config = Value::from("#0000000");
assert_eq!(<Style>::from_config(&config), None); assert!(<StyleWrapper>::from_config(&config).is_err());
let config = Value::from("#NOTHEX"); let config = Value::from("#NOTHEX");
assert_eq!(<Style>::from_config(&config), None); assert!(<StyleWrapper>::from_config(&config).is_err());
let config = Value::from("#a12BcD"); let config = Value::from("#a12BcD");
assert_eq!( assert_eq!(
<Style>::from_config(&config).unwrap(), <StyleWrapper>::from_config(&config).unwrap().0,
Color::RGB(0xA1, 0x2B, 0xCD).into() Color::RGB(0xA1, 0x2B, 0xCD).into()
); );
} }
@ -701,7 +570,7 @@ mod tests {
#[test] #[test]
fn table_get_styles_bold_italic_underline_green_dimmed_silly_caps() { fn table_get_styles_bold_italic_underline_green_dimmed_silly_caps() {
let config = Value::from("bOlD ItAlIc uNdErLiNe GrEeN diMMeD"); let config = Value::from("bOlD ItAlIc uNdErLiNe GrEeN diMMeD");
let mystyle = <Style>::from_config(&config).unwrap(); let mystyle = <StyleWrapper>::from_config(&config).unwrap().0;
assert!(mystyle.is_bold); assert!(mystyle.is_bold);
assert!(mystyle.is_italic); assert!(mystyle.is_italic);
assert!(mystyle.is_underline); assert!(mystyle.is_underline);
@ -720,7 +589,7 @@ mod tests {
#[test] #[test]
fn table_get_styles_bold_italic_underline_green_dimmed_inverted_silly_caps() { fn table_get_styles_bold_italic_underline_green_dimmed_inverted_silly_caps() {
let config = Value::from("bOlD ItAlIc uNdErLiNe GrEeN diMMeD InVeRTed"); let config = Value::from("bOlD ItAlIc uNdErLiNe GrEeN diMMeD InVeRTed");
let mystyle = <Style>::from_config(&config).unwrap(); let mystyle = <StyleWrapper>::from_config(&config).unwrap().0;
assert!(mystyle.is_bold); assert!(mystyle.is_bold);
assert!(mystyle.is_italic); assert!(mystyle.is_italic);
assert!(mystyle.is_underline); assert!(mystyle.is_underline);
@ -742,58 +611,67 @@ mod tests {
fn table_get_styles_plain_and_broken_styles() { fn table_get_styles_plain_and_broken_styles() {
// Test a "plain" style with no formatting // Test a "plain" style with no formatting
let config = Value::from(""); let config = Value::from("");
let plain_style = <Style>::from_config(&config).unwrap(); let plain_style = <StyleWrapper>::from_config(&config).unwrap().0;
assert_eq!(plain_style, ansi_term::Style::new()); assert_eq!(plain_style, ansi_term::Style::new());
// Test a string that's clearly broken // Test a string that's clearly broken
let config = Value::from("djklgfhjkldhlhk;j"); let config = Value::from("djklgfhjkldhlhk;j");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
// Test a string that's nullified by `none` // Test a string that's nullified by `none`
let config = Value::from("fg:red bg:green bold none"); let config = Value::from("fg:red bg:green bold none");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
// Test a string that's nullified by `none` at the start // Test a string that's nullified by `none` at the start
let config = Value::from("none fg:red bg:green bold"); let config = Value::from("none fg:red bg:green bold");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
} }
#[test] #[test]
fn table_get_styles_with_none() { fn table_get_styles_with_none() {
// Test that none on the end will result in None, overriding bg:none // Test that none on the end will result in None, overriding bg:none
let config = Value::from("fg:red bg:none none"); let config = Value::from("fg:red bg:none none");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
// Test that none in front will result in None, overriding bg:none // Test that none in front will result in None, overriding bg:none
let config = Value::from("none fg:red bg:none"); let config = Value::from("none fg:red bg:none");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
// Test that none in the middle will result in None, overriding bg:none // Test that none in the middle will result in None, overriding bg:none
let config = Value::from("fg:red none bg:none"); let config = Value::from("fg:red none bg:none");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
// Test that fg:none will result in None // Test that fg:none will result in None
let config = Value::from("fg:none bg:black"); let config = Value::from("fg:none bg:black");
assert!(<Style>::from_config(&config).is_none()); assert!(<StyleWrapper>::from_config(&config).is_err());
// Test that bg:none will yield a style // Test that bg:none will yield a style
let config = Value::from("fg:red bg:none"); let config = Value::from("fg:red bg:none");
assert_eq!(<Style>::from_config(&config).unwrap(), Color::Red.normal()); assert_eq!(
<StyleWrapper>::from_config(&config).unwrap().0,
Color::Red.normal()
);
// Test that bg:none will yield a style // Test that bg:none will yield a style
let config = Value::from("fg:red bg:none bold"); let config = Value::from("fg:red bg:none bold");
assert_eq!(<Style>::from_config(&config).unwrap(), Color::Red.bold()); assert_eq!(
<StyleWrapper>::from_config(&config).unwrap().0,
Color::Red.bold()
);
// Test that bg:none will overwrite the previous background colour // Test that bg:none will overwrite the previous background colour
let config = Value::from("fg:red bg:green bold bg:none"); let config = Value::from("fg:red bg:green bold bg:none");
assert_eq!(<Style>::from_config(&config).unwrap(), Color::Red.bold()); assert_eq!(
<StyleWrapper>::from_config(&config).unwrap().0,
Color::Red.bold()
);
} }
#[test] #[test]
fn table_get_styles_ordered() { fn table_get_styles_ordered() {
// Test a background style with inverted order (also test hex + ANSI) // Test a background style with inverted order (also test hex + ANSI)
let config = Value::from("bg:#050505 underline fg:120"); let config = Value::from("bg:#050505 underline fg:120");
let flipped_style = <Style>::from_config(&config).unwrap(); let flipped_style = <StyleWrapper>::from_config(&config).unwrap().0;
assert_eq!( assert_eq!(
flipped_style, flipped_style,
Style::new() Style::new()
@ -804,7 +682,7 @@ mod tests {
// Test that the last color style is always the one used // Test that the last color style is always the one used
let config = Value::from("bg:120 bg:125 bg:127 fg:127 122 125"); let config = Value::from("bg:120 bg:125 bg:127 fg:127 122 125");
let multi_style = <Style>::from_config(&config).unwrap(); let multi_style = <StyleWrapper>::from_config(&config).unwrap().0;
assert_eq!( assert_eq!(
multi_style, multi_style,
Style::new().fg(Color::Fixed(125)).on(Color::Fixed(127)) Style::new().fg(Color::Fixed(125)).on(Color::Fixed(127))

View File

@ -1,9 +1,8 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize;
use starship_module_config_derive::ModuleConfig;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct AwsConfig<'a> { pub struct AwsConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,8 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct AzureConfig<'a> { pub struct AzureConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,15 +1,14 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct BatteryConfig<'a> { pub struct BatteryConfig<'a> {
pub full_symbol: &'a str, pub full_symbol: &'a str,
pub charging_symbol: &'a str, pub charging_symbol: &'a str,
pub discharging_symbol: &'a str, pub discharging_symbol: &'a str,
pub unknown_symbol: &'a str, pub unknown_symbol: &'a str,
pub empty_symbol: &'a str, pub empty_symbol: &'a str,
#[serde(borrow)]
pub display: Vec<BatteryDisplayConfig<'a>>, pub display: Vec<BatteryDisplayConfig<'a>>,
pub disabled: bool, pub disabled: bool,
pub format: &'a str, pub format: &'a str,
@ -30,7 +29,8 @@ impl<'a> Default for BatteryConfig<'a> {
} }
} }
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct BatteryDisplayConfig<'a> { pub struct BatteryDisplayConfig<'a> {
pub threshold: i64, pub threshold: i64,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct BufConfig<'a> { pub struct BufConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CConfig<'a> { pub struct CConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CharacterConfig<'a> { pub struct CharacterConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub success_symbol: &'a str, pub success_symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CMakeConfig<'a> { pub struct CMakeConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CmdDurationConfig<'a> { pub struct CmdDurationConfig<'a> {
pub min_time: i64, pub min_time: i64,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CobolConfig<'a> { pub struct CobolConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CondaConfig<'a> { pub struct CondaConfig<'a> {
pub truncation_length: usize, pub truncation_length: usize,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ContainerConfig<'a> { pub struct ContainerConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct CrystalConfig<'a> { pub struct CrystalConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,9 @@
use crate::config::{ModuleConfig, VecOr}; use crate::config::VecOr;
use serde::{self, Serialize}; use serde::{self, Deserialize, Serialize};
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct CustomConfig<'a> { pub struct CustomConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct DartConfig<'a> { pub struct DartConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct DenoConfig<'a> { pub struct DenoConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,10 +1,9 @@
use crate::config::ModuleConfig;
use indexmap::IndexMap; use indexmap::IndexMap;
use serde::Serialize; use serde::{Deserialize, Serialize};
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct DirectoryConfig<'a> { pub struct DirectoryConfig<'a> {
pub truncation_length: i64, pub truncation_length: i64,
pub truncate_to_repo: bool, pub truncate_to_repo: bool,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct DockerContextConfig<'a> { pub struct DockerContextConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct DotnetConfig<'a> { pub struct DotnetConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ElixirConfig<'a> { pub struct ElixirConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ElmConfig<'a> { pub struct ElmConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct EnvVarConfig<'a> { pub struct EnvVarConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ErlangConfig<'a> { pub struct ErlangConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct FillConfig<'a> { pub struct FillConfig<'a> {
pub style: &'a str, pub style: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,8 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize;
use starship_module_config_derive::ModuleConfig;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct GcloudConfig<'a> { pub struct GcloudConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct GitBranchConfig<'a> { pub struct GitBranchConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct GitCommitConfig<'a> { pub struct GitCommitConfig<'a> {
pub commit_hash_length: usize, pub commit_hash_length: usize,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct GitMetricsConfig<'a> { pub struct GitMetricsConfig<'a> {
pub added_style: &'a str, pub added_style: &'a str,
pub deleted_style: &'a str, pub deleted_style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct GitStateConfig<'a> { pub struct GitStateConfig<'a> {
pub rebase: &'a str, pub rebase: &'a str,
pub merge: &'a str, pub merge: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct GitStatusConfig<'a> { pub struct GitStatusConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct GoConfig<'a> { pub struct GoConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct HaskellConfig<'a> { pub struct HaskellConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct HelmConfig<'a> { pub struct HelmConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct HgBranchConfig<'a> { pub struct HgBranchConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct HostnameConfig<'a> { pub struct HostnameConfig<'a> {
pub ssh_only: bool, pub ssh_only: bool,
pub trim_at: &'a str, pub trim_at: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct JavaConfig<'a> { pub struct JavaConfig<'a> {
pub disabled: bool, pub disabled: bool,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct JobsConfig<'a> { pub struct JobsConfig<'a> {
pub threshold: i64, pub threshold: i64,
pub symbol_threshold: i64, pub symbol_threshold: i64,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct JuliaConfig<'a> { pub struct JuliaConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct KotlinConfig<'a> { pub struct KotlinConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,10 +1,8 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize;
use starship_module_config_derive::ModuleConfig;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct KubernetesConfig<'a> { pub struct KubernetesConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,6 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize, Default)]
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize, Default)]
pub struct LineBreakConfig { pub struct LineBreakConfig {
pub disabled: bool, pub disabled: bool,
} }

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct LocalipConfig<'a> { pub struct LocalipConfig<'a> {
pub ssh_only: bool, pub ssh_only: bool,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct LuaConfig<'a> { pub struct LuaConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct MemoryConfig<'a> { pub struct MemoryConfig<'a> {
pub threshold: i64, pub threshold: i64,
pub format: &'a str, pub format: &'a str,

View File

@ -1,7 +1,5 @@
use crate::config::ModuleConfig;
use indexmap::IndexMap; use indexmap::IndexMap;
use serde::{self, Serialize}; use serde::{self, Deserialize, Serialize};
use starship_module_config_derive::ModuleConfig;
pub mod aws; pub mod aws;
pub mod azure; pub mod azure;
@ -79,177 +77,158 @@ pub mod zig;
pub use starship_root::*; pub use starship_root::*;
#[derive(Serialize, ModuleConfig, Clone)] #[derive(Serialize, Deserialize, Clone, Default)]
#[serde(default)] #[serde(default)]
pub struct FullConfig<'a> { pub struct FullConfig<'a> {
// Root config // Root config
pub format: String, #[serde(flatten)]
pub right_format: String, root: StarshipRootConfig,
pub continuation_prompt: String,
pub scan_timeout: u64,
pub command_timeout: u64,
pub add_newline: bool,
// modules // modules
#[serde(borrow)]
aws: aws::AwsConfig<'a>, aws: aws::AwsConfig<'a>,
#[serde(borrow)]
azure: azure::AzureConfig<'a>, azure: azure::AzureConfig<'a>,
#[serde(borrow)]
battery: battery::BatteryConfig<'a>, battery: battery::BatteryConfig<'a>,
#[serde(borrow)]
buf: buf::BufConfig<'a>, buf: buf::BufConfig<'a>,
#[serde(borrow)]
c: c::CConfig<'a>, c: c::CConfig<'a>,
#[serde(borrow)]
character: character::CharacterConfig<'a>, character: character::CharacterConfig<'a>,
#[serde(borrow)]
cmake: cmake::CMakeConfig<'a>, cmake: cmake::CMakeConfig<'a>,
#[serde(borrow)]
cmd_duration: cmd_duration::CmdDurationConfig<'a>, cmd_duration: cmd_duration::CmdDurationConfig<'a>,
#[serde(borrow)]
cobol: cobol::CobolConfig<'a>, cobol: cobol::CobolConfig<'a>,
#[serde(borrow)]
conda: conda::CondaConfig<'a>, conda: conda::CondaConfig<'a>,
#[serde(borrow)]
container: container::ContainerConfig<'a>, container: container::ContainerConfig<'a>,
#[serde(borrow)]
crystal: crystal::CrystalConfig<'a>, crystal: crystal::CrystalConfig<'a>,
#[serde(borrow)]
dart: dart::DartConfig<'a>, dart: dart::DartConfig<'a>,
#[serde(borrow)]
deno: deno::DenoConfig<'a>, deno: deno::DenoConfig<'a>,
#[serde(borrow)]
directory: directory::DirectoryConfig<'a>, directory: directory::DirectoryConfig<'a>,
#[serde(borrow)]
docker_context: docker_context::DockerContextConfig<'a>, docker_context: docker_context::DockerContextConfig<'a>,
#[serde(borrow)]
dotnet: dotnet::DotnetConfig<'a>, dotnet: dotnet::DotnetConfig<'a>,
#[serde(borrow)]
elixir: elixir::ElixirConfig<'a>, elixir: elixir::ElixirConfig<'a>,
#[serde(borrow)]
elm: elm::ElmConfig<'a>, elm: elm::ElmConfig<'a>,
#[serde(borrow)]
env_var: IndexMap<String, env_var::EnvVarConfig<'a>>, env_var: IndexMap<String, env_var::EnvVarConfig<'a>>,
#[serde(borrow)]
erlang: erlang::ErlangConfig<'a>, erlang: erlang::ErlangConfig<'a>,
#[serde(borrow)]
fill: fill::FillConfig<'a>, fill: fill::FillConfig<'a>,
#[serde(borrow)]
gcloud: gcloud::GcloudConfig<'a>, gcloud: gcloud::GcloudConfig<'a>,
#[serde(borrow)]
git_branch: git_branch::GitBranchConfig<'a>, git_branch: git_branch::GitBranchConfig<'a>,
#[serde(borrow)]
git_commit: git_commit::GitCommitConfig<'a>, git_commit: git_commit::GitCommitConfig<'a>,
#[serde(borrow)]
git_metrics: git_metrics::GitMetricsConfig<'a>, git_metrics: git_metrics::GitMetricsConfig<'a>,
#[serde(borrow)]
git_state: git_state::GitStateConfig<'a>, git_state: git_state::GitStateConfig<'a>,
#[serde(borrow)]
git_status: git_status::GitStatusConfig<'a>, git_status: git_status::GitStatusConfig<'a>,
#[serde(borrow)]
golang: go::GoConfig<'a>, golang: go::GoConfig<'a>,
#[serde(borrow)]
haskell: haskell::HaskellConfig<'a>, haskell: haskell::HaskellConfig<'a>,
#[serde(borrow)]
helm: helm::HelmConfig<'a>, helm: helm::HelmConfig<'a>,
#[serde(borrow)]
hg_branch: hg_branch::HgBranchConfig<'a>, hg_branch: hg_branch::HgBranchConfig<'a>,
#[serde(borrow)]
hostname: hostname::HostnameConfig<'a>, hostname: hostname::HostnameConfig<'a>,
#[serde(borrow)]
java: java::JavaConfig<'a>, java: java::JavaConfig<'a>,
#[serde(borrow)]
jobs: jobs::JobsConfig<'a>, jobs: jobs::JobsConfig<'a>,
#[serde(borrow)]
julia: julia::JuliaConfig<'a>, julia: julia::JuliaConfig<'a>,
#[serde(borrow)]
kotlin: kotlin::KotlinConfig<'a>, kotlin: kotlin::KotlinConfig<'a>,
#[serde(borrow)]
kubernetes: kubernetes::KubernetesConfig<'a>, kubernetes: kubernetes::KubernetesConfig<'a>,
line_break: line_break::LineBreakConfig, line_break: line_break::LineBreakConfig,
#[serde(borrow)]
localip: localip::LocalipConfig<'a>, localip: localip::LocalipConfig<'a>,
#[serde(borrow)]
lua: lua::LuaConfig<'a>, lua: lua::LuaConfig<'a>,
#[serde(borrow)]
memory_usage: memory_usage::MemoryConfig<'a>, memory_usage: memory_usage::MemoryConfig<'a>,
#[serde(borrow)]
nim: nim::NimConfig<'a>, nim: nim::NimConfig<'a>,
#[serde(borrow)]
nix_shell: nix_shell::NixShellConfig<'a>, nix_shell: nix_shell::NixShellConfig<'a>,
#[serde(borrow)]
nodejs: nodejs::NodejsConfig<'a>, nodejs: nodejs::NodejsConfig<'a>,
#[serde(borrow)]
ocaml: ocaml::OCamlConfig<'a>, ocaml: ocaml::OCamlConfig<'a>,
#[serde(borrow)]
openstack: openstack::OspConfig<'a>, openstack: openstack::OspConfig<'a>,
#[serde(borrow)]
package: package::PackageConfig<'a>, package: package::PackageConfig<'a>,
#[serde(borrow)]
perl: perl::PerlConfig<'a>, perl: perl::PerlConfig<'a>,
#[serde(borrow)]
php: php::PhpConfig<'a>, php: php::PhpConfig<'a>,
#[serde(borrow)]
pulumi: pulumi::PulumiConfig<'a>, pulumi: pulumi::PulumiConfig<'a>,
#[serde(borrow)]
purescript: purescript::PureScriptConfig<'a>, purescript: purescript::PureScriptConfig<'a>,
#[serde(borrow)]
python: python::PythonConfig<'a>, python: python::PythonConfig<'a>,
#[serde(borrow)]
red: red::RedConfig<'a>, red: red::RedConfig<'a>,
#[serde(borrow)]
rlang: rlang::RLangConfig<'a>, rlang: rlang::RLangConfig<'a>,
#[serde(borrow)]
ruby: ruby::RubyConfig<'a>, ruby: ruby::RubyConfig<'a>,
#[serde(borrow)]
rust: rust::RustConfig<'a>, rust: rust::RustConfig<'a>,
#[serde(borrow)]
scala: scala::ScalaConfig<'a>, scala: scala::ScalaConfig<'a>,
#[serde(borrow)]
shell: shell::ShellConfig<'a>, shell: shell::ShellConfig<'a>,
#[serde(borrow)]
shlvl: shlvl::ShLvlConfig<'a>, shlvl: shlvl::ShLvlConfig<'a>,
#[serde(borrow)]
singularity: singularity::SingularityConfig<'a>, singularity: singularity::SingularityConfig<'a>,
#[serde(borrow)]
status: status::StatusConfig<'a>, status: status::StatusConfig<'a>,
#[serde(borrow)]
sudo: sudo::SudoConfig<'a>, sudo: sudo::SudoConfig<'a>,
#[serde(borrow)]
swift: swift::SwiftConfig<'a>, swift: swift::SwiftConfig<'a>,
#[serde(borrow)]
terraform: terraform::TerraformConfig<'a>, terraform: terraform::TerraformConfig<'a>,
#[serde(borrow)]
time: time::TimeConfig<'a>, time: time::TimeConfig<'a>,
#[serde(borrow)]
username: username::UsernameConfig<'a>, username: username::UsernameConfig<'a>,
#[serde(borrow)]
vagrant: vagrant::VagrantConfig<'a>, vagrant: vagrant::VagrantConfig<'a>,
#[serde(borrow)]
vcsh: vcsh::VcshConfig<'a>, vcsh: vcsh::VcshConfig<'a>,
#[serde(borrow)]
vlang: v::VConfig<'a>, vlang: v::VConfig<'a>,
#[serde(borrow)]
zig: zig::ZigConfig<'a>, zig: zig::ZigConfig<'a>,
#[serde(borrow)]
custom: IndexMap<String, custom::CustomConfig<'a>>, custom: IndexMap<String, custom::CustomConfig<'a>>,
} }
impl<'a> Default for FullConfig<'a> {
fn default() -> Self {
Self {
format: "$all".to_string(),
right_format: "".to_string(),
continuation_prompt: "[∙](bright-black) ".to_string(),
scan_timeout: 30,
command_timeout: 500,
add_newline: true,
aws: Default::default(),
azure: Default::default(),
battery: Default::default(),
buf: Default::default(),
c: Default::default(),
character: Default::default(),
cmake: Default::default(),
cmd_duration: Default::default(),
cobol: Default::default(),
conda: Default::default(),
container: Default::default(),
crystal: Default::default(),
dart: Default::default(),
deno: Default::default(),
directory: Default::default(),
docker_context: Default::default(),
dotnet: Default::default(),
elixir: Default::default(),
elm: Default::default(),
env_var: Default::default(),
erlang: Default::default(),
fill: Default::default(),
gcloud: Default::default(),
git_branch: Default::default(),
git_commit: Default::default(),
git_metrics: Default::default(),
git_state: Default::default(),
git_status: Default::default(),
golang: Default::default(),
haskell: Default::default(),
helm: Default::default(),
hg_branch: Default::default(),
hostname: Default::default(),
java: Default::default(),
jobs: Default::default(),
julia: Default::default(),
kotlin: Default::default(),
kubernetes: Default::default(),
line_break: Default::default(),
localip: Default::default(),
lua: Default::default(),
memory_usage: Default::default(),
nim: Default::default(),
nix_shell: Default::default(),
nodejs: Default::default(),
ocaml: Default::default(),
openstack: Default::default(),
package: Default::default(),
perl: Default::default(),
php: Default::default(),
pulumi: Default::default(),
purescript: Default::default(),
python: Default::default(),
red: Default::default(),
rlang: Default::default(),
ruby: Default::default(),
rust: Default::default(),
scala: Default::default(),
shell: Default::default(),
shlvl: Default::default(),
singularity: Default::default(),
status: Default::default(),
sudo: Default::default(),
swift: Default::default(),
terraform: Default::default(),
time: Default::default(),
username: Default::default(),
vagrant: Default::default(),
vcsh: Default::default(),
vlang: Default::default(),
zig: Default::default(),
custom: Default::default(),
}
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@ -264,17 +243,4 @@ mod test {
assert!(cfg_table.contains_key(*module)); assert!(cfg_table.contains_key(*module));
} }
} }
#[test]
fn root_in_full_config() {
let full_cfg = Value::try_from(FullConfig::default()).unwrap();
let cfg_table = full_cfg.as_table().unwrap();
let root_cfg = Value::try_from(StarshipRootConfig::default()).unwrap();
let root_table = root_cfg.as_table().unwrap();
for (option, default_value) in root_table.iter() {
assert!(cfg_table.contains_key(option));
assert_eq!(&cfg_table[option], default_value);
}
}
} }

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct NimConfig<'a> { pub struct NimConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct NixShellConfig<'a> { pub struct NixShellConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct NodejsConfig<'a> { pub struct NodejsConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct OCamlConfig<'a> { pub struct OCamlConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,8 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct OspConfig<'a> { pub struct OspConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct PackageConfig<'a> { pub struct PackageConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct PerlConfig<'a> { pub struct PerlConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct PhpConfig<'a> { pub struct PhpConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct PulumiConfig<'a> { pub struct PulumiConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct PureScriptConfig<'a> { pub struct PureScriptConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,9 @@
use crate::config::{ModuleConfig, VecOr}; use crate::config::VecOr;
use serde::Serialize; use serde::{Deserialize, Serialize};
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)] #[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct PythonConfig<'a> { pub struct PythonConfig<'a> {
pub pyenv_version_name: bool, pub pyenv_version_name: bool,
pub pyenv_prefix: &'a str, pub pyenv_prefix: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct RedConfig<'a> { pub struct RedConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct RLangConfig<'a> { pub struct RLangConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct RubyConfig<'a> { pub struct RubyConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct RustConfig<'a> { pub struct RustConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ScalaConfig<'a> { pub struct ScalaConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ShellConfig<'a> { pub struct ShellConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub bash_indicator: &'a str, pub bash_indicator: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ShLvlConfig<'a> { pub struct ShLvlConfig<'a> {
pub threshold: i64, pub threshold: i64,
pub format: &'a str, pub format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct SingularityConfig<'a> { pub struct SingularityConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub format: &'a str, pub format: &'a str,

View File

@ -1,10 +1,7 @@
use crate::{config::ModuleConfig, module::ALL_MODULES}; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Serialize, Deserialize, Debug)]
use std::cmp::Ordering; #[serde(default)]
// On changes please also update the `FullConfig` struct in `mod.rs`
#[derive(Clone, Serialize)]
pub struct StarshipRootConfig { pub struct StarshipRootConfig {
pub format: String, pub format: String,
pub right_format: String, pub right_format: String,
@ -108,60 +105,3 @@ impl<'a> Default for StarshipRootConfig {
} }
} }
} }
impl<'a> ModuleConfig<'a> for StarshipRootConfig {
fn load_config(&mut self, config: &'a toml::Value) {
if let toml::Value::Table(config) = config {
config.iter().for_each(|(k, v)| match k.as_str() {
"format" => self.format.load_config(v),
"right_format" => self.right_format.load_config(v),
"continuation_prompt" => self.continuation_prompt.load_config(v),
"scan_timeout" => self.scan_timeout.load_config(v),
"command_timeout" => self.command_timeout.load_config(v),
"add_newline" => self.add_newline.load_config(v),
unknown => {
if !ALL_MODULES.contains(&unknown)
&& unknown != "custom"
&& unknown != "env_var"
{
log::warn!("Unknown config key '{}'", unknown);
let did_you_mean = &[
// Root options
"format",
"right_format",
"continuation_prompt",
"scan_timeout",
"command_timeout",
"add_newline",
// Modules
"custom",
"env_var",
]
.iter()
.chain(ALL_MODULES)
.filter_map(|field| {
let score = strsim::jaro_winkler(unknown, field);
(score > 0.8).then(|| (score, field))
})
.max_by(
|(score_a, _field_a), (score_b, _field_b)| {
score_a.partial_cmp(score_b).unwrap_or(Ordering::Equal)
},
);
if let Some((_score, field)) = did_you_mean {
log::warn!("Did you mean '{}'?", field);
}
}
}
});
}
}
fn from_config(config: &'a toml::Value) -> Option<Self> {
let mut out = Self::default();
out.load_config(config);
Some(out)
}
}

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct StatusConfig<'a> { pub struct StatusConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct SudoConfig<'a> { pub struct SudoConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub symbol: &'a str, pub symbol: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct SwiftConfig<'a> { pub struct SwiftConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct TerraformConfig<'a> { pub struct TerraformConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct TimeConfig<'a> { pub struct TimeConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct UsernameConfig<'a> { pub struct UsernameConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub style_root: &'a str, pub style_root: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct VConfig<'a> { pub struct VConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct VagrantConfig<'a> { pub struct VagrantConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct VcshConfig<'a> { pub struct VcshConfig<'a> {
pub symbol: &'a str, pub symbol: &'a str,
pub style: &'a str, pub style: &'a str,

View File

@ -1,9 +1,7 @@
use crate::config::ModuleConfig; use serde::{Deserialize, Serialize};
use serde::Serialize; #[derive(Clone, Deserialize, Serialize)]
use starship_module_config_derive::ModuleConfig; #[serde(default)]
#[derive(Clone, ModuleConfig, Serialize)]
pub struct ZigConfig<'a> { pub struct ZigConfig<'a> {
pub format: &'a str, pub format: &'a str,
pub version_format: &'a str, pub version_format: &'a str,

View File

@ -5,7 +5,7 @@ use std::process;
use std::process::Stdio; use std::process::Stdio;
use std::str::FromStr; use std::str::FromStr;
use crate::config::RootModuleConfig; use crate::config::ModuleConfig;
use crate::config::StarshipConfig; use crate::config::StarshipConfig;
use crate::configs::PROMPT_ORDER; use crate::configs::PROMPT_ORDER;
use crate::utils; use crate::utils;
@ -83,7 +83,7 @@ pub fn print_configuration(use_default: bool, paths: &[String]) {
// Get config as toml::Value // Get config as toml::Value
let user_config = get_configuration(); let user_config = get_configuration();
// Convert into FullConfig and fill in default values // Convert into FullConfig and fill in default values
let user_config = crate::configs::FullConfig::try_load(Some(&user_config)); let user_config = crate::configs::FullConfig::load(&user_config);
// Convert back to Value because toml can't serialize FullConfig directly // Convert back to Value because toml can't serialize FullConfig directly
toml::value::Value::try_from(user_config).unwrap() toml::value::Value::try_from(user_config).unwrap()
}; };

View File

@ -1,4 +1,4 @@
use crate::config::{RootModuleConfig, StarshipConfig}; use crate::config::{ModuleConfig, StarshipConfig};
use crate::configs::StarshipRootConfig; use crate::configs::StarshipRootConfig;
use crate::module::Module; use crate::module::Module;
use crate::utils::{create_command, exec_timeout, CommandOutput}; use crate::utils::{create_command, exec_timeout, CommandOutput};

View File

@ -18,6 +18,7 @@ pub mod module;
mod modules; mod modules;
pub mod print; pub mod print;
mod segment; mod segment;
mod serde_utils;
mod utils; mod utils;
#[cfg(test)] #[cfg(test)]

View File

@ -4,7 +4,7 @@ use std::str::FromStr;
use chrono::DateTime; use chrono::DateTime;
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::aws::AwsConfig; use crate::configs::aws::AwsConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;
@ -614,10 +614,6 @@ credential_process = /opt/bin/awscreds-retriever
); );
let actual = ModuleRenderer::new("aws") let actual = ModuleRenderer::new("aws")
.config(toml::toml! {
[aws]
show_duration = true
})
.env("AWS_PROFILE", "astronauts") .env("AWS_PROFILE", "astronauts")
.env("AWS_REGION", "ap-northeast-2") .env("AWS_REGION", "ap-northeast-2")
.env("AWS_ACCESS_KEY_ID", "dummy") .env("AWS_ACCESS_KEY_ID", "dummy")
@ -664,10 +660,6 @@ expiration={}
)?; )?;
let actual = ModuleRenderer::new("aws") let actual = ModuleRenderer::new("aws")
.config(toml::toml! {
[aws]
show_duration = true
})
.env("AWS_PROFILE", "astronauts") .env("AWS_PROFILE", "astronauts")
.env("AWS_REGION", "ap-northeast-2") .env("AWS_REGION", "ap-northeast-2")
.env( .env(
@ -695,10 +687,6 @@ expiration={}
#[test] #[test]
fn profile_and_region_set_show_duration() { fn profile_and_region_set_show_duration() {
let actual = ModuleRenderer::new("aws") let actual = ModuleRenderer::new("aws")
.config(toml::toml! {
[aws]
show_duration = true
})
.env("AWS_PROFILE", "astronauts") .env("AWS_PROFILE", "astronauts")
.env("AWS_REGION", "ap-northeast-2") .env("AWS_REGION", "ap-northeast-2")
.env("AWS_ACCESS_KEY_ID", "dummy") .env("AWS_ACCESS_KEY_ID", "dummy")
@ -727,7 +715,6 @@ expiration={}
let actual = ModuleRenderer::new("aws") let actual = ModuleRenderer::new("aws")
.config(toml::toml! { .config(toml::toml! {
[aws] [aws]
show_duration = true
expiration_symbol = symbol expiration_symbol = symbol
}) })
.env("AWS_PROFILE", "astronauts") .env("AWS_PROFILE", "astronauts")

View File

@ -2,7 +2,7 @@ use std::fs::File;
use std::io::{BufReader, Read}; use std::io::{BufReader, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
type JValue = serde_json::Value; type JValue = serde_json::Value;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::battery::BatteryConfig; use crate::configs::battery::BatteryConfig;
#[cfg(test)] #[cfg(test)]
use mockall::automock; use mockall::automock;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::buf::BufConfig; use crate::configs::buf::BufConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::c::CConfig; use crate::configs::c::CConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig, Shell}; use super::{Context, Module, ModuleConfig, Shell};
use crate::configs::character::CharacterConfig; use crate::configs::character::CharacterConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::formatter::VersionFormatter; use crate::formatter::VersionFormatter;
use crate::configs::cmake::CMakeConfig; use crate::configs::cmake::CMakeConfig;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::cmd_duration::CmdDurationConfig; use crate::configs::cmd_duration::CmdDurationConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::cobol::CobolConfig; use crate::configs::cobol::CobolConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use super::utils::directory::truncate; use super::utils::directory::truncate;
use crate::configs::conda::CondaConfig; use crate::configs::conda::CondaConfig;

View File

@ -7,7 +7,7 @@ pub fn module<'a>(_context: &'a Context) -> Option<Module<'a>> {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> { pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
use super::RootModuleConfig; use super::ModuleConfig;
use crate::configs::container::ContainerConfig; use crate::configs::container::ContainerConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;
use crate::utils::read_file; use crate::utils::read_file;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::crystal::CrystalConfig; use crate::configs::crystal::CrystalConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -3,7 +3,7 @@ use std::io::Write;
use std::process::{Command, Output, Stdio}; use std::process::{Command, Output, Stdio};
use std::time::Instant; use std::time::Instant;
use super::{Context, Module, RootModuleConfig, Shell}; use super::{Context, Module, ModuleConfig, Shell};
use crate::{configs::custom::CustomConfig, formatter::StringFormatter, utils::create_command}; use crate::{configs::custom::CustomConfig, formatter::StringFormatter, utils::create_command};

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::dart::DartConfig; use crate::configs::dart::DartConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::deno::DenoConfig; use crate::configs::deno::DenoConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -12,7 +12,7 @@ use unicode_segmentation::UnicodeSegmentation;
use super::{Context, Module}; use super::{Context, Module};
use super::utils::directory::truncate; use super::utils::directory::truncate;
use crate::config::RootModuleConfig; use crate::config::ModuleConfig;
use crate::configs::directory::DirectoryConfig; use crate::configs::directory::DirectoryConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -1,6 +1,6 @@
use std::path::PathBuf; use std::path::PathBuf;
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::docker_context::DockerContextConfig; use crate::configs::docker_context::DockerContextConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

View File

@ -5,7 +5,7 @@ use std::iter::Iterator;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str; use std::str;
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::dotnet::DotnetConfig; use crate::configs::dotnet::DotnetConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;
use crate::utils; use crate::utils;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig}; use super::{Context, Module, ModuleConfig};
use crate::configs::elixir::ElixirConfig; use crate::configs::elixir::ElixirConfig;
use crate::formatter::StringFormatter; use crate::formatter::StringFormatter;

Some files were not shown because too many files have changed in this diff Show More