bee_inx/
request.rs

1// Copyright 2022 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use 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/// A request for a range of milestones by [`MilestoneIndex`].
57#[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}