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:
```rust
use super::{Context, Module, RootModuleConfig};
use super::{Context, Module, ModuleConfig};
use crate::configs::php::PhpConfig;
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:
```rust
use super::{Context, Module, RootModuleConfig};
use super::{Context, Module, ModuleConfig};
use crate::configs::php::PhpConfig;
use crate::formatter::StringFormatter;

10
Cargo.lock generated
View File

@ -1583,7 +1583,6 @@ dependencies = [
"shadow-rs",
"shell-words",
"starship-battery",
"starship_module_config_derive",
"strsim",
"sys-info",
"tempfile",
@ -1617,15 +1616,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "starship_module_config_derive"
version = "0.2.1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "static_assertions"
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
# see: https://github.com/svartalf/rust-battery/issues/33
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"
sys-info = "0.9.1"
terminal_size = "0.1.17"

View File

@ -1,199 +1,59 @@
use crate::serde_utils::ValueDeserializer;
use crate::utils;
use ansi_term::{Color, Style};
use indexmap::IndexMap;
use serde::Serialize;
use ansi_term::Color;
use serde::{
de::value::Error as ValueError, de::Error as SerdeError, Deserialize, Deserializer, Serialize,
};
use std::borrow::Cow;
use std::clone::Clone;
use std::collections::HashMap;
use std::io::ErrorKind;
use std::marker::Sized;
use std::env;
use toml::Value;
/// Root config of a module.
pub trait RootModuleConfig<'a>
pub trait ModuleConfig<'a, E>
where
Self: ModuleConfig<'a> + Default,
{
/// 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,
Self: Default,
E: SerdeError,
{
/// Construct a `ModuleConfig` from a toml value.
fn from_config(_config: &'a Value) -> Option<Self> {
None
}
fn from_config(config: &'a Value) -> Result<Self, E>;
/// Merge `self` with config from a toml table.
fn load_config(&mut self, config: &'a Value) {
if let Some(value) = Self::from_config(config) {
let _ = std::mem::replace(self, value);
}
}
}
// TODO: Add logging to default implementations
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
}
/// Loads the TOML value into the config.
/// Missing values are set to their default values.
/// On error, logs an error message.
fn load(config: &'a Value) -> Self {
match Self::from_config(config) {
Ok(config) => config,
Err(e) => {
log::warn!("Failed to load config value: {}", e);
Self::default()
}
Value::String(value) => value.parse::<Self>().ok(),
_ => None,
}
}
}
impl<'a> ModuleConfig<'a> for f64 {
fn from_config(config: &Value) -> Option<Self> {
config.as_float()
/// Helper function that will call ModuleConfig::from_config(config) if config is Some,
/// or ModuleConfig::default() if config is None.
fn try_load(config: Option<&'a Value>) -> Self {
config.map(Self::load).unwrap_or_default()
}
}
impl<'a> ModuleConfig<'a> for u32 {
fn from_config(config: &Value) -> Option<Self> {
match config {
Value::Integer(value) => {
// Converting i64 to u32
if *value > 0 && *value <= u32::MAX.into() {
Some(*value as Self)
} else {
None
}
}
Value::String(value) => value.parse::<Self>().ok(),
_ => None,
}
impl<'a, T: Deserialize<'a> + Default> ModuleConfig<'a, ValueError> for T {
/// Create ValueDeserializer wrapper and use it to call Deserialize::deserialize on it.
fn from_config(config: &'a Value) -> Result<Self, ValueError> {
let deserializer = ValueDeserializer::new(config);
T::deserialize(deserializer)
}
}
impl<'a> ModuleConfig<'a> for usize {
fn from_config(config: &Value) -> Option<Self> {
match config {
Value::Integer(value) => {
if *value > 0 {
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))
}
#[derive(Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum Either<A, B> {
First(A),
Second(B),
}
/// A wrapper around `Vec<T>` that implements `ModuleConfig`, and either
@ -201,22 +61,19 @@ where
#[derive(Clone, Default, Serialize)]
pub struct VecOr<T>(pub Vec<T>);
impl<'a, T> ModuleConfig<'a> for VecOr<T>
impl<'de, T> Deserialize<'de> for VecOr<T>
where
T: ModuleConfig<'a> + Sized,
T: Deserialize<'de>,
{
fn from_config(config: &'a Value) -> Option<Self> {
if let Some(item) = T::from_config(config) {
return Some(Self(vec![item]));
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
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
string include the following:
- '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)]
mod tests {
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]
fn test_load_config() {
#[derive(Clone, Default, ModuleConfig)]
#[derive(Clone, Default, Deserialize)]
struct TestConfig<'a> {
pub symbol: &'a str,
pub disabled: bool,
@ -517,12 +397,7 @@ mod tests {
disabled = true
some_array = ["A"]
};
let mut rust_config = TestConfig {
symbol: "S ",
disabled: false,
some_array: vec!["A", "B", "C"],
};
rust_config.load_config(&config);
let rust_config = TestConfig::from_config(&config).unwrap();
assert_eq!(rust_config.symbol, "T ");
assert!(rust_config.disabled);
@ -531,15 +406,20 @@ mod tests {
#[test]
fn test_load_nested_config() {
#[derive(Clone, Default, ModuleConfig)]
#[derive(Clone, Default, Deserialize)]
#[serde(default)]
struct TestConfig<'a> {
#[serde(borrow)]
pub untracked: SegmentDisplayConfig<'a>,
#[serde(borrow)]
pub modified: SegmentDisplayConfig<'a>,
}
#[derive(PartialEq, Debug, Clone, Default, ModuleConfig)]
#[derive(PartialEq, Debug, Clone, Default, Deserialize)]
#[serde(default)]
struct SegmentDisplayConfig<'a> {
pub value: &'a str,
#[serde(deserialize_with = "deserialize_style")]
pub style: Style,
}
@ -548,23 +428,13 @@ mod tests {
modified = { value = "", style = "red" }
};
let mut git_status_config = TestConfig {
untracked: SegmentDisplayConfig {
value: "?",
style: Color::Red.bold(),
},
modified: SegmentDisplayConfig {
value: "!",
style: Color::Red.bold(),
},
};
git_status_config.load_config(&config);
let git_status_config = TestConfig::from_config(&config).unwrap();
assert_eq!(
git_status_config.untracked,
SegmentDisplayConfig {
value: "x",
style: Color::Red.bold(),
style: Style::default(),
}
);
assert_eq!(
@ -578,7 +448,8 @@ mod tests {
#[test]
fn test_load_optional_config() {
#[derive(Clone, Default, ModuleConfig)]
#[derive(Clone, Default, Deserialize)]
#[serde(default)]
struct TestConfig<'a> {
pub optional: Option<&'a str>,
pub hidden: Option<&'a str>,
@ -587,11 +458,7 @@ mod tests {
let config = toml::toml! {
optional = "test"
};
let mut rust_config = TestConfig {
optional: None,
hidden: None,
};
rust_config.load_config(&config);
let rust_config = TestConfig::from_config(&config).unwrap();
assert_eq!(rust_config.optional, Some("test"));
assert_eq!(rust_config.hidden, None);
@ -599,7 +466,8 @@ mod tests {
#[test]
fn test_load_enum_config() {
#[derive(Clone, Default, ModuleConfig)]
#[derive(Clone, Default, Deserialize)]
#[serde(default)]
struct TestConfig {
pub switch_a: Switch,
pub switch_b: Switch,
@ -612,19 +480,22 @@ mod tests {
Off,
}
impl Default for Switch {
fn default() -> Self {
Self::Off
impl<'de> Deserialize<'de> for Switch {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
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 {
fn from_config(config: &'a Value) -> Option<Self> {
match config.as_str()? {
"on" => Some(Self::On),
"off" => Some(Self::Off),
_ => None,
}
impl Default for Switch {
fn default() -> Self {
Self::Off
}
}
@ -632,12 +503,7 @@ mod tests {
switch_a = "on"
switch_b = "any"
};
let mut rust_config = TestConfig {
switch_a: Switch::Off,
switch_b: Switch::Off,
switch_c: Switch::Off,
};
rust_config.load_config(&config);
let rust_config = TestConfig::from_config(&config).unwrap();
assert_eq!(rust_config.switch_a, Switch::On);
assert_eq!(rust_config.switch_b, Switch::Off);
@ -665,23 +531,26 @@ mod tests {
#[test]
fn test_from_style() {
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]
fn test_from_hex_color_style() {
let config = Value::from("#00000");
assert_eq!(<Style>::from_config(&config), None);
assert!(<StyleWrapper>::from_config(&config).is_err());
let config = Value::from("#0000000");
assert_eq!(<Style>::from_config(&config), None);
assert!(<StyleWrapper>::from_config(&config).is_err());
let config = Value::from("#NOTHEX");
assert_eq!(<Style>::from_config(&config), None);
assert!(<StyleWrapper>::from_config(&config).is_err());
let config = Value::from("#a12BcD");
assert_eq!(
<Style>::from_config(&config).unwrap(),
<StyleWrapper>::from_config(&config).unwrap().0,
Color::RGB(0xA1, 0x2B, 0xCD).into()
);
}
@ -701,7 +570,7 @@ mod tests {
#[test]
fn table_get_styles_bold_italic_underline_green_dimmed_silly_caps() {
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_italic);
assert!(mystyle.is_underline);
@ -720,7 +589,7 @@ mod tests {
#[test]
fn table_get_styles_bold_italic_underline_green_dimmed_inverted_silly_caps() {
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_italic);
assert!(mystyle.is_underline);
@ -742,58 +611,67 @@ mod tests {
fn table_get_styles_plain_and_broken_styles() {
// Test a "plain" style with no formatting
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());
// Test a string that's clearly broken
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`
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
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]
fn table_get_styles_with_none() {
// Test that none on the end will result in None, overriding bg: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
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
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
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
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
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
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]
fn table_get_styles_ordered() {
// Test a background style with inverted order (also test hex + ANSI)
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!(
flipped_style,
Style::new()
@ -804,7 +682,7 @@ mod tests {
// 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 multi_style = <Style>::from_config(&config).unwrap();
let multi_style = <StyleWrapper>::from_config(&config).unwrap().0;
assert_eq!(
multi_style,
Style::new().fg(Color::Fixed(125)).on(Color::Fixed(127))

View File

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

View File

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

View File

@ -1,15 +1,14 @@
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 BatteryConfig<'a> {
pub full_symbol: &'a str,
pub charging_symbol: &'a str,
pub discharging_symbol: &'a str,
pub unknown_symbol: &'a str,
pub empty_symbol: &'a str,
#[serde(borrow)]
pub display: Vec<BatteryDisplayConfig<'a>>,
pub disabled: bool,
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 threshold: i64,
pub style: &'a str,

View File

@ -1,9 +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 BufConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct CConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct CharacterConfig<'a> {
pub format: &'a str,
pub success_symbol: &'a str,

View File

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

View File

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

View File

@ -1,9 +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 ContainerConfig<'a> {
pub format: &'a str,
pub symbol: &'a str,

View File

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

View File

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

View File

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

View File

@ -1,9 +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 DockerContextConfig<'a> {
pub symbol: &'a str,
pub style: &'a str,

View File

@ -1,9 +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 DotnetConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct ElixirConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct ElmConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct EnvVarConfig<'a> {
pub symbol: &'a str,
pub style: &'a str,

View File

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

View File

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

View File

@ -1,9 +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 GitBranchConfig<'a> {
pub format: &'a str,
pub symbol: &'a str,

View File

@ -1,9 +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 GitCommitConfig<'a> {
pub commit_hash_length: usize,
pub format: &'a str,

View File

@ -1,9 +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 GitMetricsConfig<'a> {
pub added_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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct GitStateConfig<'a> {
pub rebase: &'a str,
pub merge: &'a str,

View File

@ -1,9 +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 GitStatusConfig<'a> {
pub format: &'a str,
pub style: &'a str,

View File

@ -1,9 +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 GoConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct HaskellConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct HelmConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct HgBranchConfig<'a> {
pub symbol: &'a str,
pub style: &'a str,

View File

@ -1,9 +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 HostnameConfig<'a> {
pub ssh_only: bool,
pub trim_at: &'a str,

View File

@ -1,9 +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 JavaConfig<'a> {
pub disabled: bool,
pub format: &'a str,

View File

@ -1,9 +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 JobsConfig<'a> {
pub threshold: i64,
pub symbol_threshold: i64,

View File

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

View File

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

View File

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

View File

@ -1,9 +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 LocalipConfig<'a> {
pub ssh_only: bool,
pub format: &'a str,

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +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 PackageConfig<'a> {
pub format: &'a str,
pub symbol: &'a str,

View File

@ -1,9 +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 PerlConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct PhpConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct PulumiConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct PureScriptConfig<'a> {
pub 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 starship_module_config_derive::ModuleConfig;
use serde::{Deserialize, Serialize};
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct PythonConfig<'a> {
pub pyenv_version_name: bool,
pub pyenv_prefix: &'a str,

View File

@ -1,9 +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 RedConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct RLangConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct RubyConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct RustConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct ScalaConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct ShellConfig<'a> {
pub format: &'a str,
pub bash_indicator: &'a str,

View File

@ -1,9 +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 ShLvlConfig<'a> {
pub threshold: i64,
pub format: &'a str,

View File

@ -1,9 +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 SingularityConfig<'a> {
pub symbol: &'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;
use std::cmp::Ordering;
// On changes please also update the `FullConfig` struct in `mod.rs`
#[derive(Clone, Serialize)]
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(default)]
pub struct StarshipRootConfig {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct StatusConfig<'a> {
pub format: &'a str,
pub symbol: &'a str,

View File

@ -1,9 +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 SudoConfig<'a> {
pub format: &'a str,
pub symbol: &'a str,

View File

@ -1,9 +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 SwiftConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct TerraformConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct TimeConfig<'a> {
pub format: &'a str,
pub style: &'a str,

View File

@ -1,9 +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 UsernameConfig<'a> {
pub format: &'a str,
pub style_root: &'a str,

View File

@ -1,9 +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 VConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct VagrantConfig<'a> {
pub 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;
use starship_module_config_derive::ModuleConfig;
#[derive(Clone, ModuleConfig, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
#[serde(default)]
pub struct VcshConfig<'a> {
pub symbol: &'a str,
pub style: &'a str,

View File

@ -1,9 +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 ZigConfig<'a> {
pub format: &'a str,
pub version_format: &'a str,

View File

@ -5,7 +5,7 @@ use std::process;
use std::process::Stdio;
use std::str::FromStr;
use crate::config::RootModuleConfig;
use crate::config::ModuleConfig;
use crate::config::StarshipConfig;
use crate::configs::PROMPT_ORDER;
use crate::utils;
@ -83,7 +83,7 @@ pub fn print_configuration(use_default: bool, paths: &[String]) {
// Get config as toml::Value
let user_config = get_configuration();
// 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
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::module::Module;
use crate::utils::{create_command, exec_timeout, CommandOutput};

View File

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

View File

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

View File

@ -2,7 +2,7 @@ use std::fs::File;
use std::io::{BufReader, Read};
use std::path::{Path, PathBuf};
use super::{Context, Module, RootModuleConfig};
use super::{Context, Module, ModuleConfig};
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;
#[cfg(test)]
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::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::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::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig};
use super::{Context, Module, ModuleConfig};
use crate::formatter::VersionFormatter;
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::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::formatter::StringFormatter;

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig};
use super::{Context, Module, ModuleConfig};
use super::utils::directory::truncate;
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")]
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
use super::RootModuleConfig;
use super::ModuleConfig;
use crate::configs::container::ContainerConfig;
use crate::formatter::StringFormatter;
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::formatter::StringFormatter;

View File

@ -3,7 +3,7 @@ use std::io::Write;
use std::process::{Command, Output, Stdio};
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};

View File

@ -1,4 +1,4 @@
use super::{Context, Module, RootModuleConfig};
use super::{Context, Module, ModuleConfig};
use crate::configs::dart::DartConfig;
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::formatter::StringFormatter;

View File

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

View File

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

View File

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

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