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
use crate::parse::{Expr, Term, Sign};
use crate::post::{EvaluatedTerm, ExpressionResult, FormatOptions, TermSeparator, TotalPosition};
pub(crate) fn format(e: &ExpressionResult, options: FormatOptions) -> String {
let FormatOptions {
total_position,
term_separators,
term_list_parentheses,
..
} = options;
let pairs = e.pairs();
let listing = pairs.len() > 1 || pairs[0].1.parts().len() > 1;
let total_sep = if listing { " = " } else { "" };
let mut nstr = match total_position {
TotalPosition::Left => format!("{}{}", e.total(), total_sep),
_ => String::new(),
};
nstr = if pairs.is_empty() {
nstr
} else if listing {
if term_list_parentheses {
nstr.push('(');
}
let mut iter = pairs.iter();
let first = iter.next().unwrap();
let mut formatting = options;
if let TermSeparator::PlusSign = term_separators {
formatting = options.exclude_sign();
}
let form = |a, b| format_dice_term(a, b, formatting);
if let TermSeparator::PlusSign = term_separators {
match first.1.sign() {
Sign::Negative => nstr.push_str("-"),
_ => (),
}
}
nstr.push_str(&form(&first.0, &first.1));
for (before, after) in iter {
if let TermSeparator::PlusSign = term_separators {
nstr.push_str(&format!(" {} ", after.sign()));
} else {
nstr.push_str(", ");
}
nstr.push_str(&form(before, &after));
}
if term_list_parentheses {
nstr.push(')');
}
nstr
} else if let TotalPosition::Suppressed = total_position {
format!("{}", e.total())
} else {
nstr
};
if let TotalPosition::Right = total_position {
nstr.push_str(&format!("{}{}", total_sep, e.total()))
}
nstr
}
fn format_dice_term(prior: &Expr, val: &EvaluatedTerm, f: FormatOptions) -> String {
let FormatOptions {
term_parentheses, ..
} = f;
match prior.term {
Term::Constant(_) => val.format(f),
Term::Die(_) => {
let dice_term = format!("{} → {}", prior.format(f), val.format(f));
if term_parentheses {
format!("({})", dice_term)
} else {
dice_term
}
}
}
}