nu_protocol/config/
filesize.rs1use super::prelude::*;
2use crate::{Filesize, FilesizeFormatter, FilesizeUnitFormat, FormattedFilesize};
3use nu_utils::get_system_locale;
4
5impl IntoValue for FilesizeUnitFormat {
6 fn into_value(self, span: Span) -> Value {
7 self.as_str().into_value(span)
8 }
9}
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
12pub struct FilesizeConfig {
13 pub unit: FilesizeUnitFormat,
14 pub show_unit: bool,
15 pub precision: Option<usize>,
16}
17
18impl FilesizeConfig {
19 pub fn formatter(&self) -> FilesizeFormatter {
20 FilesizeFormatter::new()
21 .unit(self.unit)
22 .show_unit(self.show_unit)
23 .precision(self.precision)
24 .locale(get_system_locale()) }
26
27 pub fn format(&self, filesize: Filesize) -> FormattedFilesize {
28 self.formatter().format(filesize)
29 }
30}
31
32impl Default for FilesizeConfig {
33 fn default() -> Self {
34 Self {
35 unit: FilesizeUnitFormat::Metric,
36 show_unit: true,
37 precision: Some(1),
38 }
39 }
40}
41
42impl From<FilesizeConfig> for FilesizeFormatter {
43 fn from(config: FilesizeConfig) -> Self {
44 config.formatter()
45 }
46}
47
48impl UpdateFromValue for FilesizeConfig {
49 fn update<'a>(
50 &mut self,
51 value: &'a Value,
52 path: &mut ConfigPath<'a>,
53 errors: &mut ConfigErrors,
54 ) {
55 let Value::Record { val: record, .. } = value else {
56 errors.type_mismatch(path, Type::record(), value);
57 return;
58 };
59
60 for (col, val) in record.iter() {
61 let path = &mut path.push(col);
62 match col.as_str() {
63 "unit" => {
64 if let Ok(str) = val.as_str() {
65 match str.parse() {
66 Ok(unit) => self.unit = unit,
67 Err(_) => errors.invalid_value(path, "'metric', 'binary', 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', or 'EiB'", val),
68 }
69 } else {
70 errors.type_mismatch(path, Type::String, val)
71 }
72 }
73 "show_unit" => self.show_unit.update(val, path, errors),
74 "precision" => match *val {
75 Value::Nothing { .. } => self.precision = None,
76 Value::Int { val, .. } if val >= 0 => self.precision = Some(val as usize),
77 Value::Int { .. } => errors.invalid_value(path, "a non-negative integer", val),
78 _ => errors.type_mismatch(path, Type::custom("int or nothing"), val),
79 },
80 _ => errors.unknown_option(path, val),
81 }
82 }
83 }
84}
85
86impl IntoValue for FilesizeConfig {
87 fn into_value(self, span: Span) -> Value {
88 record! {
89 "unit" => self.unit.into_value(span),
90 "show_unit" => self.show_unit.into_value(span),
91 "precision" => self.precision.map(|x| x as i64).into_value(span),
92 }
93 .into_value(span)
94 }
95}