1use std::future::Future;
9
10use serde::Deserialize;
11use serde::Serialize;
12
13#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
28#[derive(Serialize, Deserialize)]
29pub struct Location<Name> {
30 pub descendant: Name,
31 pub distance: u64,
32}
33
34impl<Name> Location<Name> {
35 pub fn new(descendant: Name, distance: u64) -> Self {
36 Self {
37 descendant,
38 distance,
39 }
40 }
41
42 pub fn map_descendant<T, F>(self, f: F) -> Location<T>
48 where
49 F: FnOnce(Name) -> T,
50 {
51 let new_name = f(self.descendant);
52 Location::new(new_name, self.distance)
53 }
54
55 pub fn try_map_descendant<T, E, F>(self, f: F) -> Result<Location<T>, E>
56 where
57 F: FnOnce(Name) -> Result<T, E>,
58 {
59 let new_name = f(self.descendant)?;
60 Ok(Location::new(new_name, self.distance))
61 }
62
63 pub async fn then_descendant<T, Fut, F>(self, f: F) -> Location<T>
64 where
65 F: FnOnce(Name) -> Fut,
66 Fut: Future<Output = T>,
67 {
68 let new_name = f(self.descendant).await;
69 Location::new(new_name, self.distance)
70 }
71
72 pub async fn and_then_descendant<T, E, Fut, F>(self, f: F) -> Result<Location<T>, E>
73 where
74 F: FnOnce(Name) -> Fut,
75 Fut: Future<Output = Result<T, E>>,
76 {
77 let new_name = f(self.descendant).await?;
78 Ok(Location::new(new_name, self.distance))
79 }
80
81 pub fn with_descendant<T>(self, descendant: T) -> Location<T> {
82 Location::new(descendant, self.distance)
83 }
84}
85
86#[cfg(any(test, feature = "for-tests"))]
87use quickcheck::Arbitrary;
88#[cfg(any(test, feature = "for-tests"))]
89use quickcheck::Gen;
90
91#[cfg(any(test, feature = "for-tests"))]
92impl<Name> Arbitrary for Location<Name>
93where
94 Name: Arbitrary,
95{
96 fn arbitrary(g: &mut Gen) -> Self {
97 Location {
98 descendant: Name::arbitrary(g),
99 distance: u64::arbitrary(g),
100 }
101 }
102}