misskey_util/
timeline.rs

1use std::ops::{Range, RangeFrom, RangeFull, RangeTo};
2
3use chrono::{DateTime, Utc};
4use derivative::Derivative;
5use misskey_api::{model::id::Id, Entity};
6
7/// Range in the timeline.
8#[derive(Derivative)]
9#[derivative(Debug(bound = ""))]
10#[derivative(PartialEq(bound = ""), Eq(bound = ""))]
11#[derivative(Clone(bound = ""), Copy(bound = ""))]
12pub enum TimelineRange<E> {
13    /// Range in the timeline bounded by time.
14    DateTime {
15        /// The lower bound of the range (inclusive), if it exists.
16        since_date: Option<DateTime<Utc>>,
17        /// The upper bound of the range (exclusive), if it exists.
18        until_date: Option<DateTime<Utc>>,
19    },
20    /// Range in the timeline bounded by note IDs.
21    Id {
22        /// The lower bound of the range (inclusive), if it exists.
23        since_id: Option<Id<E>>,
24        /// The upper bound of the range (exclusive), if it exists.
25        until_id: Option<Id<E>>,
26    },
27    /// Unbounded range.
28    Unbounded,
29}
30
31impl<E> TimelineRange<E> {
32    /// Returns [`TimelineRange`] for the range to a specified point on the timeline.
33    pub fn until(cursor: TimelineCursor<E>) -> Self {
34        match cursor {
35            TimelineCursor::Id(id) => TimelineRange::Id {
36                since_id: None,
37                until_id: Some(id),
38            },
39            TimelineCursor::DateTime(date) => TimelineRange::DateTime {
40                since_date: None,
41                until_date: Some(date),
42            },
43        }
44    }
45
46    /// Returns [`TimelineRange`] for the range from a specified point on the timeline.
47    pub fn since(cursor: TimelineCursor<E>) -> Self {
48        match cursor {
49            TimelineCursor::Id(id) => TimelineRange::Id {
50                since_id: Some(id),
51                until_id: None,
52            },
53            TimelineCursor::DateTime(date) => TimelineRange::DateTime {
54                since_date: Some(date),
55                until_date: None,
56            },
57        }
58    }
59}
60
61impl<E: Entity> From<RangeFull> for TimelineRange<E> {
62    fn from(RangeFull: RangeFull) -> Self {
63        TimelineRange::Unbounded
64    }
65}
66
67// We can't impl<E: Entity, R: EntityRef<E>> From<$range<R>> for TimelineRange<E>
68// because impl for DateTime<Utc> and R conflicts
69macro_rules! impl_from_range {
70    ($range:ident, $arg:ident, $since:expr, $until:expr) => {
71        impl<E: Entity> From<$range<Id<E>>> for TimelineRange<E> {
72            fn from($arg: $range<Id<E>>) -> Self {
73                TimelineRange::Id {
74                    since_id: $since,
75                    until_id: $until,
76                }
77            }
78        }
79
80        impl<E: Entity> From<$range<&E>> for TimelineRange<E> {
81            fn from($arg: $range<&E>) -> Self {
82                TimelineRange::Id {
83                    since_id: $since.map(Entity::id),
84                    until_id: $until.map(Entity::id),
85                }
86            }
87        }
88
89        impl<E: Entity> From<$range<DateTime<Utc>>> for TimelineRange<E> {
90            fn from($arg: $range<DateTime<Utc>>) -> Self {
91                TimelineRange::DateTime {
92                    since_date: $since,
93                    until_date: $until,
94                }
95            }
96        }
97    };
98}
99
100impl_from_range! { Range, range, Some(range.start), Some(range.end) }
101impl_from_range! { RangeFrom, range, Some(range.start), None }
102impl_from_range! { RangeTo, range, None, Some(range.end) }
103
104/// Point on the timeline.
105#[derive(Derivative)]
106#[derivative(Debug(bound = ""))]
107#[derivative(PartialEq(bound = ""), Eq(bound = ""))]
108#[derivative(Clone(bound = ""), Copy(bound = ""))]
109pub enum TimelineCursor<E> {
110    /// Point on the timeline specified by time.
111    DateTime(DateTime<Utc>),
112    /// Point on the timeline specified by note ID.
113    Id(Id<E>),
114}
115
116// We can't impl<E: Entity, R: EntityRef<E>> From<R> for TimelineCursor<E>
117// because impl for DateTime<Utc> and R conflicts
118impl<E: Entity> From<DateTime<Utc>> for TimelineCursor<E> {
119    fn from(time: DateTime<Utc>) -> Self {
120        TimelineCursor::DateTime(time)
121    }
122}
123
124impl<E: Entity> From<Id<E>> for TimelineCursor<E> {
125    fn from(id: Id<E>) -> Self {
126        TimelineCursor::Id(id)
127    }
128}
129
130impl<E: Entity> From<&E> for TimelineCursor<E> {
131    fn from(entity: &E) -> Self {
132        TimelineCursor::Id(entity.id())
133    }
134}