1use std::ops::{Bound, RangeBounds};
5
6use bee_block::payload::milestone::{MilestoneId, MilestoneIndex};
7use inx::proto;
8
9pub enum MilestoneRequest {
10 MilestoneIndex(MilestoneIndex),
11 MilestoneId(MilestoneId),
12}
13
14impl From<MilestoneRequest> for proto::MilestoneRequest {
15 fn from(value: MilestoneRequest) -> Self {
16 match value {
17 MilestoneRequest::MilestoneIndex(MilestoneIndex(milestone_index)) => Self {
18 milestone_index,
19 milestone_id: None,
20 },
21 MilestoneRequest::MilestoneId(milestone_id) => Self {
22 milestone_index: 0,
23 milestone_id: Some(milestone_id.into()),
24 },
25 }
26 }
27}
28
29impl<T: Into<u32>> From<T> for MilestoneRequest {
30 fn from(value: T) -> Self {
31 Self::MilestoneIndex(MilestoneIndex(value.into()))
32 }
33}
34
35fn to_milestone_range_request<T, I>(range: T) -> proto::MilestoneRangeRequest
36where
37 T: RangeBounds<I>,
38 I: Into<u32> + Copy,
39{
40 let start_milestone_index = match range.start_bound() {
41 Bound::Included(&idx) => idx.into(),
42 Bound::Excluded(&idx) => idx.into() + 1,
43 Bound::Unbounded => 0,
44 };
45 let end_milestone_index = match range.end_bound() {
46 Bound::Included(&idx) => idx.into(),
47 Bound::Excluded(&idx) => idx.into() - 1,
48 Bound::Unbounded => 0,
49 };
50 proto::MilestoneRangeRequest {
51 start_milestone_index,
52 end_milestone_index,
53 }
54}
55
56#[derive(Clone, Debug, PartialEq)]
58pub struct MilestoneRangeRequest(proto::MilestoneRangeRequest);
59
60impl<T> From<T> for MilestoneRangeRequest
61where
62 T: RangeBounds<u32>,
63{
64 fn from(value: T) -> MilestoneRangeRequest {
65 MilestoneRangeRequest(to_milestone_range_request(value))
66 }
67}
68
69impl From<MilestoneRangeRequest> for proto::MilestoneRangeRequest {
70 fn from(value: MilestoneRangeRequest) -> Self {
71 value.0
72 }
73}
74
75#[cfg(test)]
76mod test {
77 use super::*;
78
79 #[test]
80 fn exclusive() {
81 let range = MilestoneRangeRequest::from(17..43);
82 assert_eq!(
83 range,
84 MilestoneRangeRequest(proto::MilestoneRangeRequest {
85 start_milestone_index: 17,
86 end_milestone_index: 42
87 })
88 );
89 }
90
91 #[test]
92 fn inclusive() {
93 let range = MilestoneRangeRequest::from(17..=42);
94 assert_eq!(
95 range,
96 MilestoneRangeRequest(proto::MilestoneRangeRequest {
97 start_milestone_index: 17,
98 end_milestone_index: 42
99 })
100 );
101 }
102}