mirror of
https://github.com/MalteT/mensa.git
synced 2024-10-22 21:59:17 +02:00
Fix #15, don't panic on closed pipes
Logging will now use stderr instead of stdout.
This commit is contained in:
parent
13ed33f51f
commit
485676095e
|
@ -9,7 +9,7 @@
|
||||||
# If omitted, `$XDG_CONFIG_HOME/mensa/config.toml` or
|
# If omitted, `$XDG_CONFIG_HOME/mensa/config.toml` or
|
||||||
# `$HOME/.config/mensa/config.toml` (if $XDG_CONFIG_HOME is unset)
|
# `$HOME/.config/mensa/config.toml` (if $XDG_CONFIG_HOME is unset)
|
||||||
# are checked.
|
# are checked.
|
||||||
#
|
#
|
||||||
# All options can also be specified on the command line or in the environment
|
# All options can also be specified on the command line or in the environment
|
||||||
# 1) CLI flags take precedence over
|
# 1) CLI flags take precedence over
|
||||||
# 2) ENVIRONMENT VARIABLES, which overwrite
|
# 2) ENVIRONMENT VARIABLES, which overwrite
|
||||||
|
|
15
src/cache/dummy.rs
vendored
15
src/cache/dummy.rs
vendored
|
@ -38,10 +38,6 @@ impl Cache for DummyCache {
|
||||||
let entry = read
|
let entry = read
|
||||||
.get(&path)
|
.get(&path)
|
||||||
.expect("BUG: Metadata exists, but entry does not!");
|
.expect("BUG: Metadata exists, but entry does not!");
|
||||||
eprintln!(
|
|
||||||
"Cache read for {:?}\n-> Returning: {:#?}",
|
|
||||||
meta.integrity, entry.text
|
|
||||||
);
|
|
||||||
Ok(entry.text.clone())
|
Ok(entry.text.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +52,6 @@ impl Cache for DummyCache {
|
||||||
text: text.to_owned(),
|
text: text.to_owned(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
eprintln!(
|
|
||||||
"Cache write to {:?}\n-> Headers: {:#?}\n-> Content: {:#?}",
|
|
||||||
url, headers, text
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +59,6 @@ impl Cache for DummyCache {
|
||||||
let hash = path_from_key(url);
|
let hash = path_from_key(url);
|
||||||
let read = self.content.read().expect("Reading cache failed");
|
let read = self.content.read().expect("Reading cache failed");
|
||||||
let entry = read.get(&hash);
|
let entry = read.get(&hash);
|
||||||
eprintln!("Cache Metadata for {:?}: {:?}", url, entry);
|
|
||||||
match entry {
|
match entry {
|
||||||
Some(entry) => Ok(Some(clone_metadata(&entry.meta))),
|
Some(entry) => Ok(Some(clone_metadata(&entry.meta))),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
|
@ -76,7 +67,6 @@ impl Cache for DummyCache {
|
||||||
|
|
||||||
fn clear(&self) -> Result<()> {
|
fn clear(&self) -> Result<()> {
|
||||||
self.content.write().expect("Writing cache failed").clear();
|
self.content.write().expect("Writing cache failed").clear();
|
||||||
eprintln!("Cache cleared");
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,9 +82,7 @@ impl Cache for DummyCache {
|
||||||
|
|
||||||
fn path_from_key(key: &str) -> String {
|
fn path_from_key(key: &str) -> String {
|
||||||
let integrity = Integrity::from(key);
|
let integrity = Integrity::from(key);
|
||||||
let path = path_from_integrity(&integrity);
|
path_from_integrity(&integrity)
|
||||||
eprintln!("Hashing key {:?} -> {:#?}", key, path);
|
|
||||||
path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path_from_integrity(integrity: &Integrity) -> String {
|
fn path_from_integrity(integrity: &Integrity) -> String {
|
||||||
|
@ -102,7 +90,6 @@ fn path_from_integrity(integrity: &Integrity) -> String {
|
||||||
let (algorithm, digest) = integrity.to_hex();
|
let (algorithm, digest) = integrity.to_hex();
|
||||||
path += &algorithm.to_string();
|
path += &algorithm.to_string();
|
||||||
path += &digest;
|
path += &digest;
|
||||||
eprintln!("Hashing integrity {:?} -> {:#?}", integrity, path);
|
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
src/cache/tests.rs
vendored
2
src/cache/tests.rs
vendored
|
@ -14,7 +14,7 @@ fn print_cache_list(header: &'static str) -> Result<()> {
|
||||||
CACHE.list()?.iter().for_each(|meta| {
|
CACHE.list()?.iter().for_each(|meta| {
|
||||||
let age_ms = meta.time;
|
let age_ms = meta.time;
|
||||||
let cache_age = chrono::Utc.timestamp((age_ms / 1000) as i64, (age_ms % 1000) as u32);
|
let cache_age = chrono::Utc.timestamp((age_ms / 1000) as i64, (age_ms % 1000) as u32);
|
||||||
eprintln!(
|
println!(
|
||||||
"| - {}\n| SIZE: {}\n| AGE: {}",
|
"| - {}\n| SIZE: {}\n| AGE: {}",
|
||||||
meta.key, meta.size, cache_age
|
meta.key, meta.size, cache_age
|
||||||
)
|
)
|
||||||
|
|
|
@ -99,13 +99,12 @@ impl Canteen {
|
||||||
.initial_indent(ADRESS_INDENT)
|
.initial_indent(ADRESS_INDENT)
|
||||||
.subsequent_indent(ADRESS_INDENT),
|
.subsequent_indent(ADRESS_INDENT),
|
||||||
);
|
);
|
||||||
println!(
|
try_println!(
|
||||||
"{} {}\n{}",
|
"{} {}\n{}",
|
||||||
color!(format!("{:>4}", self.id); bold, bright_yellow),
|
color!(format!("{:>4}", self.id); bold, bright_yellow),
|
||||||
color!(self.meta()?.name; bold),
|
color!(self.meta()?.name; bold),
|
||||||
color!(address; bright_black),
|
color!(address; bright_black),
|
||||||
);
|
)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> CanteenId {
|
pub fn id(&self) -> CanteenId {
|
||||||
|
@ -132,7 +131,7 @@ impl Canteen {
|
||||||
Self::print_all_json(canteens)
|
Self::print_all_json(canteens)
|
||||||
} else {
|
} else {
|
||||||
for canteen in canteens {
|
for canteen in canteens {
|
||||||
println!();
|
try_println!()?;
|
||||||
canteen.print()?;
|
canteen.print()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
50
src/main.rs
50
src/main.rs
|
@ -57,7 +57,7 @@
|
||||||
//!
|
//!
|
||||||
//! ### Examples
|
//! ### Examples
|
||||||
//!
|
//!
|
||||||
//! ####
|
//! ####
|
||||||
//! <details>
|
//! <details>
|
||||||
//! <summary><b>Meals on monday</b> (<i>Click me!</i>)</summary>
|
//! <summary><b>Meals on monday</b> (<i>Click me!</i>)</summary>
|
||||||
//!
|
//!
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
//! ┊
|
//! ┊
|
||||||
//! ┊ ╭───╴Bohnengemüse
|
//! ┊ ╭───╴Bohnengemüse
|
||||||
//! ┊ ├─╴Gemüsebeilage 🌱
|
//! ┊ ├─╴Gemüsebeilage 🌱
|
||||||
//! ┊ ╰╴( 0.55€ )
|
//! ┊ ╰╴( 0.55€ )
|
||||||
//! ...
|
//! ...
|
||||||
//! ```
|
//! ```
|
||||||
//! </details>
|
//! </details>
|
||||||
|
@ -95,13 +95,13 @@
|
||||||
//!
|
//!
|
||||||
//! ```console
|
//! ```console
|
||||||
//! $ mensa tags
|
//! $ mensa tags
|
||||||
//!
|
//!
|
||||||
//! 0 Acidifier
|
//! 0 Acidifier
|
||||||
//! Contains artificial acidifier
|
//! Contains artificial acidifier
|
||||||
//!
|
//!
|
||||||
//! 1 Alcohol
|
//! 1 Alcohol
|
||||||
//! Contains alcohol
|
//! Contains alcohol
|
||||||
//!
|
//!
|
||||||
//! 2 Antioxidant
|
//! 2 Antioxidant
|
||||||
//! Contains an antioxidant
|
//! Contains an antioxidant
|
||||||
//! ...
|
//! ...
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
//!
|
//!
|
||||||
//! ```console
|
//! ```console
|
||||||
//! $ mensa meals close --date sun
|
//! $ mensa meals close --date sun
|
||||||
//!
|
//!
|
||||||
//! Leipzig, Cafeteria Dittrichring
|
//! Leipzig, Cafeteria Dittrichring
|
||||||
//! ┊
|
//! ┊
|
||||||
//! ┊ ╭───╴Vegetarisch gefüllte Zucchini
|
//! ┊ ╭───╴Vegetarisch gefüllte Zucchini
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
//! ┊ ├╴Rucola-Kartoffelpüree
|
//! ┊ ├╴Rucola-Kartoffelpüree
|
||||||
//! ┊ ├╴Tomaten-Ratatouille-Soße
|
//! ┊ ├╴Tomaten-Ratatouille-Soße
|
||||||
//! ┊ ╰╴( 2.65€ ) 2 11 12 19
|
//! ┊ ╰╴( 2.65€ ) 2 11 12 19
|
||||||
//!
|
//!
|
||||||
//! Leipzig, Mensa am Park
|
//! Leipzig, Mensa am Park
|
||||||
//! ┊
|
//! ┊
|
||||||
//! ┊ ╭───╴Apfelrotkohl
|
//! ┊ ╭───╴Apfelrotkohl
|
||||||
|
@ -147,12 +147,14 @@
|
||||||
//! - `$HOME/Library/Application Support/mensa/config.toml` on **macOS**,
|
//! - `$HOME/Library/Application Support/mensa/config.toml` on **macOS**,
|
||||||
//! - `{FOLDERID_RoamingAppData}\mensa\config.toml` on **Windows**
|
//! - `{FOLDERID_RoamingAppData}\mensa\config.toml` on **Windows**
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
|
||||||
use cache::Cache;
|
use cache::Cache;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use directories_next::ProjectDirs;
|
use directories_next::ProjectDirs;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tracing::error;
|
use tracing::{error, info};
|
||||||
|
|
||||||
/// Colorizes the output.
|
/// Colorizes the output.
|
||||||
///
|
///
|
||||||
|
@ -211,6 +213,18 @@ macro_rules! if_plain {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Safer `println` which doesn't panic, but errors.
|
||||||
|
macro_rules! try_println {
|
||||||
|
() => {
|
||||||
|
try_println!("\n")
|
||||||
|
};
|
||||||
|
($str:literal $(, $args:expr )* $(,)?) => ({
|
||||||
|
use std::io::Write;
|
||||||
|
writeln!(::std::io::stdout(), $str, $( $args ),* )
|
||||||
|
.map_err(|why| crate::error::Error::Io(why, "printing"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
mod canteen;
|
mod canteen;
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -240,17 +254,25 @@ lazy_static! {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let res = real_main();
|
match real_main() {
|
||||||
match res {
|
Ok(_) => Ok(()),
|
||||||
Ok(_) => {}
|
// Ignore broken pipe errors, but log them
|
||||||
Err(ref why) => error!("{}", why),
|
Err(Error::Io(err, _)) if err.kind() == io::ErrorKind::BrokenPipe => {
|
||||||
|
info!("Pipe was closed");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(why) => {
|
||||||
|
error!("{}", why);
|
||||||
|
Err(why)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn real_main() -> Result<()> {
|
fn real_main() -> Result<()> {
|
||||||
// Initialize logger
|
// Initialize logger
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::FmtSubscriber::builder()
|
||||||
|
.with_writer(::std::io::stderr)
|
||||||
|
.init();
|
||||||
// Clear cache if requested
|
// Clear cache if requested
|
||||||
if CONF.args.clear_cache {
|
if CONF.args.clear_cache {
|
||||||
CACHE.clear()?;
|
CACHE.clear()?;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use lazy_static::lazy_static;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::get_sane_terminal_dimensions;
|
use crate::{error::Result, get_sane_terminal_dimensions};
|
||||||
|
|
||||||
use super::{MealId, Meta, PRE};
|
use super::{MealId, Meta, PRE};
|
||||||
|
|
||||||
|
@ -27,39 +27,40 @@ pub struct MealComplete<'c> {
|
||||||
|
|
||||||
impl<'c> MealComplete<'c> {
|
impl<'c> MealComplete<'c> {
|
||||||
/// Print this [`MealComplete`] to the terminal.
|
/// Print this [`MealComplete`] to the terminal.
|
||||||
pub fn print(&self, highlight: bool) {
|
pub fn print(&self, highlight: bool) -> Result<()> {
|
||||||
let (width, _height) = get_sane_terminal_dimensions();
|
let (width, _height) = get_sane_terminal_dimensions();
|
||||||
// Print meal name
|
// Print meal name
|
||||||
self.print_name_to_terminal(width, highlight);
|
self.print_name_to_terminal(width, highlight)?;
|
||||||
// Get notes, i.e. allergenes, descriptions, tags
|
// Get notes, i.e. allergenes, descriptions, tags
|
||||||
self.print_category_and_primary_tags(highlight);
|
self.print_category_and_primary_tags(highlight)?;
|
||||||
self.print_descriptions(width, highlight);
|
self.print_descriptions(width, highlight)?;
|
||||||
self.print_price_and_secondary_tags(highlight);
|
self.print_price_and_secondary_tags(highlight)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_name_to_terminal(&self, width: usize, highlight: bool) {
|
fn print_name_to_terminal(&self, width: usize, highlight: bool) -> Result<()> {
|
||||||
let max_name_width = width - NAME_PRE.width() - PRE.width();
|
let max_name_width = width - NAME_PRE.width() - PRE.width();
|
||||||
let mut name_parts = textwrap::wrap(&self.meta.name, max_name_width).into_iter();
|
let mut name_parts = textwrap::wrap(&self.meta.name, max_name_width).into_iter();
|
||||||
// There will always be a first part of the splitted string
|
// There will always be a first part of the splitted string
|
||||||
let first_name_part = name_parts.next().unwrap();
|
let first_name_part = name_parts.next().unwrap();
|
||||||
println!(
|
try_println!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
*PRE,
|
*PRE,
|
||||||
hl_if(highlight, *NAME_PRE),
|
hl_if(highlight, *NAME_PRE),
|
||||||
color!(hl_if(highlight, first_name_part); bold),
|
color!(hl_if(highlight, first_name_part); bold),
|
||||||
);
|
)?;
|
||||||
for name_part in name_parts {
|
for name_part in name_parts {
|
||||||
let name_part = hl_if(highlight, name_part);
|
let name_part = hl_if(highlight, name_part);
|
||||||
println!(
|
try_println!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
*PRE,
|
*PRE,
|
||||||
hl_if(highlight, *NAME_CONTINUE_PRE),
|
hl_if(highlight, *NAME_CONTINUE_PRE),
|
||||||
color!(name_part; bold),
|
color!(name_part; bold),
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_category_and_primary_tags(&self, highlight: bool) {
|
fn print_category_and_primary_tags(&self, highlight: bool) -> Result<()> {
|
||||||
let mut tag_str = self
|
let mut tag_str = self
|
||||||
.meta
|
.meta
|
||||||
.tags
|
.tags
|
||||||
|
@ -69,39 +70,40 @@ impl<'c> MealComplete<'c> {
|
||||||
let tag_str_colored =
|
let tag_str_colored =
|
||||||
if_plain!(color!(tag_str.join(" "); bright_black), tag_str.join(", "));
|
if_plain!(color!(tag_str.join(" "); bright_black), tag_str.join(", "));
|
||||||
let comma_if_plain = if_plain!("", ",");
|
let comma_if_plain = if_plain!("", ",");
|
||||||
println!(
|
try_println!(
|
||||||
"{}{}{}{} {}",
|
"{}{}{}{} {}",
|
||||||
*PRE,
|
*PRE,
|
||||||
hl_if(highlight, *CATEGORY_PRE),
|
hl_if(highlight, *CATEGORY_PRE),
|
||||||
color!(self.meta.category; bright_blue),
|
color!(self.meta.category; bright_blue),
|
||||||
color!(comma_if_plain; bright_black),
|
color!(comma_if_plain; bright_black),
|
||||||
tag_str_colored
|
tag_str_colored
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_descriptions(&self, width: usize, highlight: bool) {
|
fn print_descriptions(&self, width: usize, highlight: bool) -> Result<()> {
|
||||||
let max_note_width = width - OTHER_NOTE_PRE.width() - PRE.width();
|
let max_note_width = width - OTHER_NOTE_PRE.width() - PRE.width();
|
||||||
for note in &self.meta.descs {
|
for note in &self.meta.descs {
|
||||||
let mut note_parts = textwrap::wrap(note, max_note_width).into_iter();
|
let mut note_parts = textwrap::wrap(note, max_note_width).into_iter();
|
||||||
// There will always be a first part in the splitted string
|
// There will always be a first part in the splitted string
|
||||||
println!(
|
try_println!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
*PRE,
|
*PRE,
|
||||||
hl_if(highlight, *OTHER_NOTE_PRE),
|
hl_if(highlight, *OTHER_NOTE_PRE),
|
||||||
note_parts.next().unwrap()
|
note_parts.next().unwrap()
|
||||||
);
|
)?;
|
||||||
for part in note_parts {
|
for part in note_parts {
|
||||||
println!(
|
try_println!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
*PRE,
|
*PRE,
|
||||||
hl_if(highlight, *OTHER_NOTE_CONTINUE_PRE),
|
hl_if(highlight, *OTHER_NOTE_CONTINUE_PRE),
|
||||||
part
|
part
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_price_and_secondary_tags(&self, highlight: bool) {
|
fn print_price_and_secondary_tags(&self, highlight: bool) -> Result<()> {
|
||||||
let prices = self.meta.prices.to_terminal_string();
|
let prices = self.meta.prices.to_terminal_string();
|
||||||
let mut secondary: Vec<_> = self
|
let mut secondary: Vec<_> = self
|
||||||
.meta
|
.meta
|
||||||
|
@ -111,13 +113,13 @@ impl<'c> MealComplete<'c> {
|
||||||
.collect();
|
.collect();
|
||||||
secondary.sort_unstable();
|
secondary.sort_unstable();
|
||||||
let secondary_str = secondary.iter().map(|tag| tag.as_id()).join(" ");
|
let secondary_str = secondary.iter().map(|tag| tag.as_id()).join(" ");
|
||||||
println!(
|
try_println!(
|
||||||
"{}{}{} {}",
|
"{}{}{} {}",
|
||||||
*PRE,
|
*PRE,
|
||||||
hl_if(highlight, *PRICES_PRE),
|
hl_if(highlight, *PRICES_PRE),
|
||||||
prices,
|
prices,
|
||||||
color!(secondary_str; bright_black),
|
color!(secondary_str; bright_black),
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl Meal {
|
||||||
let day = CONF.date();
|
let day = CONF.date();
|
||||||
for canteen in canteens {
|
for canteen in canteens {
|
||||||
let name = canteen.name()?;
|
let name = canteen.name()?;
|
||||||
println!("\n {}", color!(name; bright_black));
|
try_println!("\n {}", color!(name; bright_black))?;
|
||||||
match canteen.meals_at_mut(day)? {
|
match canteen.meals_at_mut(day)? {
|
||||||
Some(meals) => {
|
Some(meals) => {
|
||||||
let mut printed_at_least_one_meal = false;
|
let mut printed_at_least_one_meal = false;
|
||||||
|
@ -104,18 +104,16 @@ impl Meal {
|
||||||
let complete = meal.complete()?;
|
let complete = meal.complete()?;
|
||||||
if filter.is_match(&complete) {
|
if filter.is_match(&complete) {
|
||||||
let is_fav = favs.is_non_empty_match(&complete);
|
let is_fav = favs.is_non_empty_match(&complete);
|
||||||
println!("{}", *PRE);
|
try_println!("{}", *PRE)?;
|
||||||
complete.print(is_fav);
|
complete.print(is_fav)?;
|
||||||
printed_at_least_one_meal = true;
|
printed_at_least_one_meal = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !printed_at_least_one_meal {
|
if !printed_at_least_one_meal {
|
||||||
println!("{} {}", *PRE, color!("no matching meals found"; dimmed));
|
try_println!("{} {}", *PRE, color!("no matching meals found"; dimmed))?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => try_println!("{} {}", *PRE, color!("closed"; dimmed))?,
|
||||||
println!("{} {}", *PRE, color!("closed"; dimmed))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
10
src/tag.rs
10
src/tag.rs
|
@ -212,7 +212,7 @@ impl Tag {
|
||||||
/// Print this tag.
|
/// Print this tag.
|
||||||
///
|
///
|
||||||
/// Does **not** respect `--json`, use [`Self::print_all`].
|
/// Does **not** respect `--json`, use [`Self::print_all`].
|
||||||
pub fn print(&self) {
|
pub fn print(&self) -> Result<()> {
|
||||||
let emoji = if CONF.args.plain && self.is_primary() {
|
let emoji = if CONF.args.plain && self.is_primary() {
|
||||||
format!("{:>width$}", "-", width = ID_WIDTH)
|
format!("{:>width$}", "-", width = ID_WIDTH)
|
||||||
} else {
|
} else {
|
||||||
|
@ -231,12 +231,12 @@ impl Tag {
|
||||||
.initial_indent(TEXT_INDENT)
|
.initial_indent(TEXT_INDENT)
|
||||||
.subsequent_indent(TEXT_INDENT),
|
.subsequent_indent(TEXT_INDENT),
|
||||||
);
|
);
|
||||||
println!(
|
try_println!(
|
||||||
"{} {}\n{}",
|
"{} {}\n{}",
|
||||||
color!(emoji; bright_yellow, bold),
|
color!(emoji; bright_yellow, bold),
|
||||||
color!(self; bold),
|
color!(self; bold),
|
||||||
color!(description; bright_black),
|
color!(description; bright_black),
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print all tags.
|
/// Print all tags.
|
||||||
|
@ -245,8 +245,8 @@ impl Tag {
|
||||||
Self::print_all_json()
|
Self::print_all_json()
|
||||||
} else {
|
} else {
|
||||||
for tag in Tag::iter() {
|
for tag in Tag::iter() {
|
||||||
println!();
|
try_println!()?;
|
||||||
tag.print();
|
tag.print()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue