mirror of
https://github.com/starship/starship.git
synced 2025-02-02 11:29:40 +01:00
Merge branch 'positional-segments' into style-variables
This commit is contained in:
commit
21d40c6f4e
26
Cargo.lock
generated
26
Cargo.lock
generated
@ -310,7 +310,7 @@ dependencies = [
|
||||
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -366,12 +366,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.12.3+1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.12.4+1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -472,7 +472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.12.3+1.0.0"
|
||||
version = "0.12.4+1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -851,7 +851,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.6"
|
||||
version = "1.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1012,7 +1012,7 @@ dependencies = [
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"git2 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"git2 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1024,11 +1024,11 @@ dependencies = [
|
||||
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_env_logger 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"starship_module_config_derive 0.1.1",
|
||||
"sysinfo 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sysinfo 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1070,7 +1070,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.13.3"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1330,7 +1330,7 @@ dependencies = [
|
||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
"checksum gethostname 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
|
||||
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
"checksum git2 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2cfb93ca10f2934069c3aaafb753fbe0663f08ee009a01b6d62e062391447b15"
|
||||
"checksum git2 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfc6e264105ef4bf1f5c9a0907f285b43ed2ede987b4876556d0478359f0a0f"
|
||||
"checksum hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
|
||||
"checksum http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
|
||||
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||
@ -1343,7 +1343,7 @@ dependencies = [
|
||||
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
"checksum lexical-core 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f86d66d380c9c5a685aaac7a11818bdfa1f733198dfd9ec09c70b762cd12ad6f"
|
||||
"checksum libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||
"checksum libgit2-sys 0.12.3+1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7637dc15e7f05a16011723e0448655081fc01a374bcd368e2c9b9c7f5c5ab3ea"
|
||||
"checksum libgit2-sys 0.12.4+1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef2870ecd7b50a76391b108edc2c62283ad2b62e5b1ab4d5263ef1cd04ef1c44"
|
||||
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
@ -1389,7 +1389,7 @@ dependencies = [
|
||||
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
|
||||
"checksum regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
|
||||
"checksum regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
|
||||
"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
|
||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
|
||||
@ -1410,7 +1410,7 @@ dependencies = [
|
||||
"checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||
"checksum sysinfo 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5a0338198966bde7feb14b011a33d404a62a6e03b843352c71512a2a002634b7"
|
||||
"checksum sysinfo 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d070254b7172eee9eb3990bea8f72aeabfe1226c40bf71a52e4fe75777812e9a"
|
||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
|
||||
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
||||
|
@ -31,7 +31,7 @@ tls-vendored = ["native-tls/vendored"]
|
||||
clap = "2.33.0"
|
||||
ansi_term = "0.12.1"
|
||||
dirs = "2.0.2"
|
||||
git2 = { version = "0.13.1", default-features = false, features = [] }
|
||||
git2 = { version = "0.13.3", default-features = false, features = [] }
|
||||
toml = { version = "0.5.6", features = ["preserve_order"] }
|
||||
serde_json = "1.0.51"
|
||||
rayon = "1.3.0"
|
||||
@ -45,14 +45,14 @@ unicode-segmentation = "1.6.0"
|
||||
gethostname = "0.2.1"
|
||||
once_cell = "1.3.1"
|
||||
chrono = "0.4"
|
||||
sysinfo = "0.13.3"
|
||||
sysinfo = "0.14.1"
|
||||
byte-unit = "3.0.3"
|
||||
starship_module_config_derive = { version = "0.1.0", path = "starship_module_config_derive" }
|
||||
yaml-rust = "0.4"
|
||||
pest = "^2.1"
|
||||
pest_derive = "^2.1"
|
||||
nom = "5.1.1"
|
||||
regex = "1.3.6"
|
||||
regex = "1.3.7"
|
||||
os_info = "2.0.2"
|
||||
urlencoding = "1.0.0"
|
||||
open = "1.4.0"
|
||||
|
@ -37,7 +37,7 @@
|
||||
<p align="center">
|
||||
<a href="https://starship.rs">Website</a>
|
||||
·
|
||||
<a href="#-installation">Installation</a>
|
||||
<a href="#🚀-installation">Installation</a>
|
||||
·
|
||||
<a href="https://starship.rs/config/">Configuration</a>
|
||||
</p>
|
||||
@ -130,6 +130,8 @@
|
||||
</p>
|
||||
|
||||
|
||||
<a name="🚀-installation"></a>
|
||||
|
||||
## 🚀 Installation
|
||||
|
||||
### Prerequisites
|
||||
|
@ -1191,8 +1191,6 @@ symbol = "⚙️ "
|
||||
The `singularity` module shows the current singularity image, if inside a container
|
||||
and `$SINGULARITY_NAME` is set.
|
||||
|
||||
:::
|
||||
|
||||
### Options
|
||||
|
||||
| Variable | Default | Description |
|
||||
|
@ -204,7 +204,6 @@ fn get_starship_config() -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use os_info;
|
||||
use std::env;
|
||||
|
||||
#[test]
|
||||
|
@ -423,7 +423,6 @@ fn parse_color_string(color_string: &str) -> Option<ansi_term::Color> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use starship_module_config_derive::ModuleConfig;
|
||||
use toml;
|
||||
|
||||
#[test]
|
||||
fn test_load_config() {
|
||||
|
@ -1,4 +1,10 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
/// Type that holds a number of variables of type `T`
|
||||
pub trait VariableHolder<T> {
|
||||
fn get_variables(&self) -> BTreeSet<T>;
|
||||
}
|
||||
|
||||
pub struct TextGroup<'a> {
|
||||
pub format: Vec<FormatElement<'a>>,
|
||||
@ -9,9 +15,56 @@ pub enum FormatElement<'a> {
|
||||
Text(Cow<'a, str>),
|
||||
Variable(Cow<'a, str>),
|
||||
TextGroup(TextGroup<'a>),
|
||||
Positional(Vec<FormatElement<'a>>),
|
||||
}
|
||||
|
||||
pub enum StyleElement<'a> {
|
||||
Text(Cow<'a, str>),
|
||||
Variable(Cow<'a, str>),
|
||||
}
|
||||
|
||||
impl<'a> VariableHolder<Cow<'a, str>> for FormatElement<'a> {
|
||||
fn get_variables(&self) -> BTreeSet<Cow<'a, str>> {
|
||||
match self {
|
||||
FormatElement::Variable(var) => {
|
||||
let mut variables = BTreeSet::new();
|
||||
variables.insert(var.clone());
|
||||
variables
|
||||
}
|
||||
FormatElement::TextGroup(textgroup) => textgroup.format.get_variables(),
|
||||
FormatElement::Positional(format) => format.get_variables(),
|
||||
_ => Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VariableHolder<Cow<'a, str>> for Vec<FormatElement<'a>> {
|
||||
fn get_variables(&self) -> BTreeSet<Cow<'a, str>> {
|
||||
self.iter().fold(BTreeSet::new(), |mut acc, el| {
|
||||
acc.extend(el.get_variables());
|
||||
acc
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VariableHolder<Cow<'a, str>> for StyleElement<'a> {
|
||||
fn get_variables(&self) -> BTreeSet<Cow<'a, str>> {
|
||||
match self {
|
||||
StyleElement::Variable(var) => {
|
||||
let mut variables = BTreeSet::new();
|
||||
variables.insert(var.clone());
|
||||
variables
|
||||
}
|
||||
_ => Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VariableHolder<Cow<'a, str>> for Vec<&StyleElement<'a>> {
|
||||
fn get_variables(&self) -> BTreeSet<Cow<'a, str>> {
|
||||
self.iter().fold(BTreeSet::new(), |mut acc, el| {
|
||||
acc.extend(el.get_variables());
|
||||
acc
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,18 @@ use super::model::*;
|
||||
#[grammar = "formatter/spec.pest"]
|
||||
struct IdentParser;
|
||||
|
||||
fn _parse_value(value: Pair<Rule>) -> FormatElement {
|
||||
match value.as_rule() {
|
||||
Rule::text => FormatElement::Text(_parse_text(value).into()),
|
||||
Rule::variable => FormatElement::Variable(_parse_variable(value).into()),
|
||||
Rule::textgroup => FormatElement::TextGroup(_parse_textgroup(value)),
|
||||
Rule::positional => {
|
||||
FormatElement::Positional(_parse_format(value.into_inner().next().unwrap()))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn _parse_textgroup(textgroup: Pair<Rule>) -> TextGroup {
|
||||
let mut inner_rules = textgroup.into_inner();
|
||||
let format = inner_rules.next().unwrap();
|
||||
@ -29,15 +41,7 @@ fn _parse_text(text: Pair<Rule>) -> String {
|
||||
}
|
||||
|
||||
fn _parse_format(format: Pair<Rule>) -> Vec<FormatElement> {
|
||||
format
|
||||
.into_inner()
|
||||
.map(|pair| match pair.as_rule() {
|
||||
Rule::text => FormatElement::Text(_parse_text(pair).into()),
|
||||
Rule::variable => FormatElement::Variable(_parse_variable(pair).into()),
|
||||
Rule::textgroup => FormatElement::TextGroup(_parse_textgroup(pair)),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect()
|
||||
format.into_inner().map(_parse_value).collect()
|
||||
}
|
||||
|
||||
fn _parse_style(style: Pair<Rule>) -> Vec<StyleElement> {
|
||||
@ -55,12 +59,7 @@ pub fn parse(format: &str) -> Result<Vec<FormatElement>, Error<Rule>> {
|
||||
IdentParser::parse(Rule::expression, format).map(|pairs| {
|
||||
pairs
|
||||
.take_while(|pair| pair.as_rule() != Rule::EOI)
|
||||
.map(|pair| match pair.as_rule() {
|
||||
Rule::text => FormatElement::Text(_parse_text(pair).into()),
|
||||
Rule::variable => FormatElement::Variable(_parse_variable(pair).into()),
|
||||
Rule::textgroup => FormatElement::TextGroup(_parse_textgroup(pair)),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.map(_parse_value)
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
//
|
||||
// Should be started with SOI and ended with EOI, with a format string in it.
|
||||
expression = _{ SOI ~ value* ~ EOI }
|
||||
value = _{ text | variable | textgroup }
|
||||
value = _{ text | variable | textgroup | positional }
|
||||
|
||||
// Variable
|
||||
//
|
||||
@ -36,7 +36,7 @@ escape = _{ "\\" ~ escaped_char }
|
||||
escaped_char = { "[" | "]" | "(" | ")" | "\\" | "$" }
|
||||
|
||||
// TextGroup
|
||||
//
|
||||
//
|
||||
// A textgroup is a pair of `format` and `style` (`[format](style)`)
|
||||
//
|
||||
// - `format`: A format string, can contain any number of variables, texts or textgroups.
|
||||
@ -44,3 +44,8 @@ escaped_char = { "[" | "]" | "(" | ")" | "\\" | "$" }
|
||||
textgroup = { "[" ~ format ~ "]" ~ "(" ~ style ~ ")" }
|
||||
format = { value* }
|
||||
style = { (variable | string)* }
|
||||
|
||||
// Positional
|
||||
//
|
||||
// A positional format string that won't render if all the containing variables are empty.
|
||||
positional = { "(" ~ format ~ ")" }
|
||||
|
@ -1,7 +1,8 @@
|
||||
use ansi_term::Style;
|
||||
use pest::error::Error;
|
||||
use rayon::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use crate::config::parse_style_string;
|
||||
use crate::segment::Segment;
|
||||
@ -35,7 +36,29 @@ impl<'a> StringFormatter<'a> {
|
||||
pub fn new(format: &'a str) -> Result<Self, Error<Rule>> {
|
||||
parse(format)
|
||||
.map(|format| {
|
||||
let (variables, style_variables) = _get_variables(&format);
|
||||
// Cache all variables
|
||||
let variables = VariableMapType::from_iter(
|
||||
format
|
||||
.get_variables()
|
||||
.into_iter()
|
||||
.map(|key| (key.to_string(), None))
|
||||
.collect::<Vec<(String, Option<_>)>>(),
|
||||
);
|
||||
let style_elements = format
|
||||
.iter()
|
||||
.flat_map(|el| match el {
|
||||
FormatElement::TextGroup(textgroup) => Some(&textgroup.style),
|
||||
_ => None,
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<&StyleElement>>();
|
||||
let style_variables = StyleVariableMapType::from_iter(
|
||||
style_elements
|
||||
.get_variables()
|
||||
.into_iter()
|
||||
.map(|key| (key.to_string(), None))
|
||||
.collect::<Vec<(String, Option<_>)>>(),
|
||||
);
|
||||
(format, variables, style_variables)
|
||||
})
|
||||
.map(|(format, variables, style_variables)| Self {
|
||||
@ -46,9 +69,9 @@ impl<'a> StringFormatter<'a> {
|
||||
}
|
||||
|
||||
/// Maps variable name to its value
|
||||
pub fn map(mut self, mapper: impl Fn(&str) -> Option<String> + Sync) -> Self {
|
||||
pub fn map<T: Into<String>>(mut self, mapper: impl Fn(&str) -> Option<T> + Sync) -> Self {
|
||||
self.variables.par_iter_mut().for_each(|(key, value)| {
|
||||
*value = mapper(key).map(VariableValue::Plain);
|
||||
*value = mapper(key).map(|var| var.into()).map(VariableValue::Plain);
|
||||
});
|
||||
self
|
||||
}
|
||||
@ -126,12 +149,12 @@ impl<'a> StringFormatter<'a> {
|
||||
}
|
||||
FormatElement::Variable(name) => variables
|
||||
.get(name.as_ref())
|
||||
.map(|segments| {
|
||||
let value = segments.clone().unwrap_or_default();
|
||||
match value {
|
||||
.and_then(|segments| {
|
||||
Some(match segments.clone()? {
|
||||
VariableValue::Styled(segments) => segments
|
||||
.into_iter()
|
||||
.map(|mut segment| {
|
||||
// Derive upper style if the style of segments are none.
|
||||
if !segment.has_style() {
|
||||
if let Some(style) = style {
|
||||
segment.set_style(style);
|
||||
@ -143,9 +166,25 @@ impl<'a> StringFormatter<'a> {
|
||||
VariableValue::Plain(text) => {
|
||||
vec![_new_segment(name.to_string(), text, style)]
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
FormatElement::Positional(format) => {
|
||||
// Show the positional format string if all the variables inside are not
|
||||
// none.
|
||||
let should_show: bool = format.get_variables().iter().any(|var| {
|
||||
variables
|
||||
.get(var.as_ref())
|
||||
.map(|segments| segments.is_some())
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
if should_show {
|
||||
_parse_format(format, style, variables, style_variables)
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@ -159,51 +198,10 @@ impl<'a> StringFormatter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract variable names from an array of `FormatElement` into a `BTreeMap`
|
||||
fn _get_variables<'a>(format: &[FormatElement<'a>]) -> (VariableMapType, StyleVariableMapType) {
|
||||
let mut variables: VariableMapType = Default::default();
|
||||
let mut style_variables: StyleVariableMapType = Default::default();
|
||||
|
||||
fn _push_variables_from_textgroup<'a>(
|
||||
variables: &mut VariableMapType,
|
||||
style_variables: &mut StyleVariableMapType,
|
||||
textgroup: &'a TextGroup<'a>,
|
||||
) {
|
||||
for el in &textgroup.format {
|
||||
match el {
|
||||
FormatElement::Variable(name) => _push_variable(variables, name.as_ref()),
|
||||
FormatElement::TextGroup(textgroup) => {
|
||||
_push_variables_from_textgroup(variables, style_variables, &textgroup)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
for el in &textgroup.style {
|
||||
if let StyleElement::Variable(name) = el {
|
||||
_push_style_variable(style_variables, name.as_ref())
|
||||
}
|
||||
}
|
||||
impl<'a> VariableHolder<String> for StringFormatter<'a> {
|
||||
fn get_variables(&self) -> BTreeSet<String> {
|
||||
BTreeSet::from_iter(self.variables.keys().cloned())
|
||||
}
|
||||
|
||||
fn _push_variable<'a>(variables: &mut VariableMapType, name: &'a str) {
|
||||
variables.insert(name.to_owned(), None);
|
||||
}
|
||||
|
||||
fn _push_style_variable<'a>(style_variables: &mut StyleVariableMapType, name: &'a str) {
|
||||
style_variables.insert(name.to_owned(), None);
|
||||
}
|
||||
|
||||
for el in format {
|
||||
match el {
|
||||
FormatElement::Variable(name) => _push_variable(&mut variables, name.as_ref()),
|
||||
FormatElement::TextGroup(textgroup) => {
|
||||
_push_variables_from_textgroup(&mut variables, &mut style_variables, &textgroup)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
(variables, style_variables)
|
||||
}
|
||||
|
||||
/// Helper function to create a new segment
|
||||
@ -365,6 +363,42 @@ mod tests {
|
||||
match_next!(result_iter, "styled_no_modifier", styled_no_modifier_style);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_positional() {
|
||||
const FORMAT_STR: &str = "($some) should render but ($none) shouldn't";
|
||||
|
||||
let formatter = StringFormatter::new(FORMAT_STR)
|
||||
.unwrap()
|
||||
.map(|var| match var {
|
||||
"some" => Some("$some"),
|
||||
_ => None,
|
||||
});
|
||||
let result = formatter.parse(None);
|
||||
let mut result_iter = result.iter();
|
||||
match_next!(result_iter, "$some", None);
|
||||
match_next!(result_iter, " should render but ", None);
|
||||
match_next!(result_iter, " shouldn't", None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_positional() {
|
||||
const FORMAT_STR: &str = "($some ($none)) and ($none ($some))";
|
||||
|
||||
let formatter = StringFormatter::new(FORMAT_STR)
|
||||
.unwrap()
|
||||
.map(|var| match var {
|
||||
"some" => Some("$some"),
|
||||
_ => None,
|
||||
});
|
||||
let result = formatter.parse(None);
|
||||
let mut result_iter = result.iter();
|
||||
match_next!(result_iter, "$some", None);
|
||||
match_next!(result_iter, " ", None);
|
||||
match_next!(result_iter, " and ", None);
|
||||
match_next!(result_iter, " ", None);
|
||||
match_next!(result_iter, "$some", None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_error() {
|
||||
// brackets without escape
|
||||
|
@ -51,7 +51,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_crystal_files() -> io::Result<()> {
|
||||
|
@ -63,7 +63,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn test_parse_elixir_version() {
|
||||
|
@ -42,7 +42,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_elm() -> io::Result<()> {
|
||||
|
@ -70,7 +70,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_go_files() -> io::Result<()> {
|
||||
|
@ -43,7 +43,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_stack_yaml() -> io::Result<()> {
|
||||
|
@ -55,7 +55,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_julia_file() -> io::Result<()> {
|
||||
|
@ -1,4 +1,3 @@
|
||||
use dirs;
|
||||
use yaml_rust::YamlLoader;
|
||||
|
||||
use std::env;
|
||||
|
@ -41,7 +41,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_node_files() -> io::Result<()> {
|
||||
|
@ -5,7 +5,6 @@ use crate::utils;
|
||||
|
||||
use regex::Regex;
|
||||
use serde_json as json;
|
||||
use toml;
|
||||
|
||||
use super::{RootModuleConfig, SegmentConfig};
|
||||
use crate::configs::package::PackageConfig;
|
||||
|
@ -58,7 +58,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn test_format_php_version() {
|
||||
|
@ -56,7 +56,6 @@ mod tests {
|
||||
use ansi_term::Color;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn folder_without_ruby_files() -> io::Result<()> {
|
||||
|
@ -2,7 +2,6 @@ use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use ansi_term::Color;
|
||||
use tempfile;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
|
@ -2,7 +2,6 @@ use ansi_term::Color;
|
||||
use remove_dir_all::remove_dir_all;
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
use tempfile;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
|
@ -3,7 +3,6 @@ use std::ffi::OsStr;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{self, Error, ErrorKind, Write};
|
||||
use std::process::{Command, Stdio};
|
||||
use tempfile;
|
||||
|
||||
#[test]
|
||||
fn show_nothing_on_empty_dir() -> io::Result<()> {
|
||||
|
@ -4,7 +4,6 @@ use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use tempfile;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
|
@ -3,7 +3,6 @@ use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::{env, io};
|
||||
use tempfile;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
|
@ -2,7 +2,6 @@ use std::fs::File;
|
||||
use std::io;
|
||||
|
||||
use ansi_term::Color;
|
||||
use tempfile;
|
||||
|
||||
use crate::common::{self, TestCommand};
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use ansi_term::Color;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Write};
|
||||
use tempfile;
|
||||
|
||||
use crate::common;
|
||||
use crate::common::TestCommand;
|
||||
|
Loading…
Reference in New Issue
Block a user