1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Reporting functions.

use crate::err::Error;
use std::fmt::{Display, Write};

/// Length allocated to name printing.
const NAME_LENGTH: usize = 32;

/// Report the value of an object.
/// # Errors
/// if the object could not be written to a string.
#[inline]
pub fn obj<T: Display>(name: &str, obj: T) -> Result<String, Error> {
    let mut s = String::new();
    write!(s, "{}", obj)?;
    if s.contains('\n') {
        Ok(format!(
            "{:>name_len$}   .\n  {}",
            name,
            s.replace('\n', "\n  "),
            name_len = NAME_LENGTH
        ))
    } else {
        Ok(format!(
            "{:>name_len$} :  {}",
            name,
            s,
            name_len = NAME_LENGTH
        ))
    }
}

/// Report the value of an object.
/// # Errors
/// if the object could not be written.
#[inline]
pub fn obj_units<T: Display>(name: &str, obj: T, units: &str) -> Result<String, Error> {
    let mut s = String::new();
    write!(s, "{}", obj)?;
    if s.contains('\n') {
        Ok(format!(
            "{:>name_len$}  .\n  {} [{}]",
            name,
            s.replace('\n', "\n  "),
            units,
            name_len = NAME_LENGTH
        ))
    } else {
        Ok(format!(
            "{:>name_len$} :  {} [{}]",
            name,
            s,
            units,
            name_len = NAME_LENGTH
        ))
    }
}

/// Report an object and either its associated name, or a human readable string if supplied.
#[macro_export]
macro_rules! report {
    ($expression: expr) => {
        println!(
            "{}",
            arctk::report::obj(stringify!($expression), $expression)
                .expect("Could not write object.")
        );
    };

    ($desc: expr, $expression: expr) => {
        println!(
            "{}",
            arctk::report::obj($desc, $expression).expect("Could not write object.")
        );
    };

    ($desc: expr, $expression: expr, $units: tt) => {
        println!(
            "{}",
            arctk::report::obj_units($desc, $expression, $units).expect("Could not write object.")
        );
    };
}

/// Write a list of items as a string.
/// # Errors
/// if a list item could not be written.
#[inline]
fn list_string<T: Display>(list: &[T]) -> Result<String, Error> {
    let mut s = String::new();
    for item in list {
        write!(s, "{:>item_len$} ", item, item_len = NAME_LENGTH / 2)?;
    }

    if !s.is_empty() {
        s.pop();
    }

    Ok(s)
}

/// Report a list of items.
/// # Errors
/// if a list item could not be written.
#[inline]
pub fn list<T: Display>(name: &str, list: &[T]) -> Result<String, Error> {
    obj(name, list_string(list)?)
}

/// Report a list of items.
/// # Errors
/// if a list item could not be written.
#[inline]
pub fn list_units<T: Display>(name: &str, list: &[T], units: &str) -> Result<String, Error> {
    obj_units(name, list_string(list)?, units)
}

/// Report a list of items with an associated name, or a human readable string if supplied.
#[macro_export]
macro_rules! report_list {
    ($expression: expr) => {
        println!(
            "{}",
            arctk::report::list(stringify!($expression), $expression)
                .expect("Could not write object.")
        );
    };

    ($desc: expr, $expression: expr) => {
        println!(
            "{}",
            arctk::report::list($desc, $expression).expect("Could not write object.")
        );
    };

    ($desc: expr, $expression: expr, $units: tt) => {
        println!(
            "{}",
            arctk::report::list_units($desc, $expression, $units).expect("Could not write object.")
        );
    };
}