1use serde::{Deserialize, Serialize};
4
5#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone, Copy)]
7pub struct ValueStep<T> {
8 initial: T,
10 #[serde(skip_serializing_if = "Option::is_none")]
12 step: Option<T>,
13}
14
15impl<T> ValueStep<T> {
16 pub fn new(initial: T, step: Option<T>) -> Self {
18 Self { initial, step }
19 }
20
21 pub fn get_initial(&self) -> &T {
23 &self.initial
24 }
25
26 pub fn get_step(&self) -> &Option<T> {
28 &self.step
29 }
30
31 pub fn convert_into<U>(self) -> ValueStep<U>
33 where
34 T: Into<U>,
35 {
36 self.convert_with(|v| v.into())
37 }
38
39 pub fn convert_with<F, U>(self, mut convert: F) -> ValueStep<U>
41 where
42 F: FnMut(T) -> U,
43 {
44 let Self { initial, step } = self;
45
46 ValueStep {
47 initial: convert(initial),
48 step: step.map(|e| {
49 #[allow(clippy::redundant_closure)]
50 convert(e)
51 }),
52 }
53 }
54
55 pub fn try_convert_with<F, U, E>(self, mut convert: F) -> Result<ValueStep<U>, E>
57 where
58 F: FnMut(T) -> Result<U, E>,
59 {
60 let Self { initial, step } = self;
61
62 let _step = match step {
63 None => None,
64 Some(step) => Some(convert(step)?),
65 };
66
67 Ok(ValueStep {
68 initial: convert(initial)?,
69 step: _step,
70 })
71 }
72}
73
74impl<T: std::fmt::Display> std::fmt::Display for ValueStep<T> {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 let Self { initial, step } = &self;
77
78 match step {
79 Some(_step) => write!(f, "{}..(/{})", initial, _step),
80 None => write!(f, "{}..", initial),
81 }
82 }
83}