complete_api/
complete_api.rs1use dice_parser::{DiceError, DiceExpr, ExprResult, Keep, RollSpec};
6use rand::{SeedableRng, rngs::StdRng};
7
8fn main() {
9 println!("1. Parsing and expressions");
15 let parsed = DiceExpr::parse("2d6+3").unwrap();
16 println!(" 1.1 Parsing e.g. \"2d6+3\" yields:");
17 println!(" {:?}", parsed);
18
19 let literal = DiceExpr::Literal(5);
21 println!(" 1.2 A literal expression \"5\": ");
22 println!(" {:?}", literal);
23
24 let roll = DiceExpr::Roll(RollSpec::new(2, 6, None));
25 println!(" 1.3 A single roll expression corresponding to 2d6:",);
26 println!(" {:?}", roll);
27
28 let sum = DiceExpr::Sum(Box::new(roll.clone()), Box::new(literal.clone()));
29 println!(" 1.4 A sum of two expression, e.g. \"2d6+5\":");
30 println!(" {:?}", sum);
31
32 let _diff = DiceExpr::Difference(Box::new(roll.clone()), Box::new(DiceExpr::Literal(1)));
33 println!(" 1.5 A difference of two expressions, e.g. \"2d6-1\":",);
34 println!(" {:?}", _diff);
35
36 println!("\n 1.6 DiceExpr::roll() - Rolling expressions");
38 let result1 = parsed.roll().unwrap();
39 println!(" An expression, 2d6+3: {}", result1.total);
40 let result2 = literal.roll().unwrap();
41 println!(" A literal 5: {}", result2.total);
42 let result3 = roll.roll().unwrap();
43 println!(" A single roll 2d6: {}", result3.total);
44 let result4 = sum.roll().unwrap();
45 println!(" A manual sum, 2d6+5: {}", result4.total);
46 let result5 = _diff.roll().unwrap();
47 println!(" A manual diff, 2d6-1: {}", result5.total);
48
49 println!("\n 1.7 DiceExpr::roll_with_rng() - Roll with custom RNG");
50 let rng = StdRng::seed_from_u64(42);
51 let result6 = DiceExpr::parse("1d20").unwrap().roll_with_rng(rng).unwrap();
52 println!(" Rolling 1d20: {}", result6.total);
53
54 println!("\n2. RollSpec Usage:");
58 println!(" Struct with public fields and constructor\n");
59
60 let spec = RollSpec::new(4, 6, Some(Keep::Highest(3)));
61 println!(" RollSpec::new(4, 6, Some(Keep::Highest(3)))");
62 println!(" - count: {}", spec.count);
63 println!(" - sides: {}", spec.sides);
64 println!(" - keep: {:?}", spec.keep);
65
66 println!("\n3. Keep Usage:");
70 println!(" Enum with public variants\n");
71
72 let _keep_high = Keep::Highest(3);
73 println!(" {:?} - Keep 3 highest dice", _keep_high);
74
75 let _keep_low = Keep::Lowest(1);
76 println!(" {:?} - Keep 1 lowest die", _keep_high);
77
78 let _advantage = RollSpec::new(2, 20, Some(Keep::Highest(1)));
80 let _disadvantage = RollSpec::new(2, 20, Some(Keep::Lowest(1)));
81 println!("\n Example with Advantage:");
82 println!(
83 " {:?}, result: {}",
84 _advantage,
85 DiceExpr::Roll(_advantage.clone()).roll().unwrap().total
86 );
87 println!("\n Example with Disadvantage:");
88 println!(
89 " {:?}, result: {}",
90 _disadvantage,
91 DiceExpr::Roll(_disadvantage.clone()).roll().unwrap().total
92 );
93
94 println!("\n4. ExprResult Usage:");
98 println!(" Struct with public fields\n");
99
100 let expr = DiceExpr::parse("2d6+3").unwrap();
101 let result: ExprResult = expr.roll().unwrap();
102
103 println!(" ExprResult from rolling 2d6+3:");
104 println!(" - total: {} (final result)", result.total);
105 println!(" - rolls: {:?} (individual dice)", result.rolls);
106 println!(" - modifier: {} (constant modifiers)", result.modifier);
107
108 println!("\n5. DiceError Usage:");
112 println!(" Enum with public variants for error handling\n");
113
114 if let Err(DiceError::ParseError {
116 kind,
117 input,
118 start,
119 stop: _,
120 }) = DiceExpr::parse("invalid")
121 {
122 println!(" DiceError::ParseError:");
123 println!(" - kind: {:?}", kind);
124 println!(" - input: {}", input);
125 println!(" - start: {}", start);
126 }
127
128 if let Err(DiceError::SyntaxError { expected, .. }) = DiceExpr::parse("-2d6") {
130 println!("\n DiceError::SyntaxError:");
131 if let Some(exp) = expected {
132 println!(" - expected: {}", exp);
133 }
134 }
135
136 if let Err(DiceError::TrailingInput { pos, .. }) = DiceExpr::parse("2d6 extra") {
138 println!("\n DiceError::TrailingInput:");
139 println!(" - pos: {}", pos);
140 }
141
142 let bad_spec = RollSpec::new(2, 6, Some(Keep::Highest(5)));
144 if let Err(DiceError::InvalidSpec(spec, msg)) = DiceExpr::Roll(bad_spec).roll() {
145 println!("\n DiceError::InvalidSpec:");
146 println!(" - spec: {:?}", spec);
147 println!(" - message: {}", msg);
148 }
149
150 println!("\n6. Complete Example:");
154 println!(" Building a complex expression with all features\n");
155
156 println!(" Rolling D&D ability scores (4d6 drop lowest):");
158 let ability_roll = DiceExpr::Roll(RollSpec::new(4, 6, Some(Keep::Highest(3))));
159
160 for i in 1..=6 {
161 if let Ok(result) = ability_roll.roll() {
162 println!(
163 " Ability {}: {} (rolls: {:?})",
164 i, result.total, result.rolls
165 );
166 }
167 }
168}