phabricator_api/edge/
search.rs1use crate::types::{Cursor, Phid};
2use crate::ApiRequest;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
6pub enum Type {
7 #[serde(rename = "task.subtask")]
8 TaskSubtask,
9 #[serde(rename = "task.parent")]
10 TaskParent,
11}
12
13#[derive(Serialize, Debug, Default)]
14pub struct Search {
15 #[serde(rename = "sourcePHIDs")]
16 pub sources: Vec<Phid>,
17 pub types: Vec<Type>,
18 #[serde(rename = "destinationPHIDs")]
19 pub destinations: Option<Vec<Phid>>,
20}
21
22#[derive(Serialize, Debug)]
23pub struct SearchCursor<'a> {
24 #[serde(flatten)]
25 pub cursor: &'a Cursor,
26 #[serde(flatten)]
27 pub search: &'a Search,
28}
29
30#[derive(Deserialize, Debug)]
31pub struct Data {
32 #[serde(rename = "sourcePHID")]
33 pub source: Phid,
34 #[serde(rename = "edgeType")]
35 pub ty: Type,
36 #[serde(rename = "destinationPHID")]
37 pub dest: Phid,
38}
39
40#[derive(Deserialize, Debug)]
41pub struct SearchResult {
42 pub data: Vec<Data>,
43 pub cursor: Cursor,
44}
45
46impl ApiRequest for Search {
47 type Reply = SearchResult;
48 const ROUTE: &'static str = "api/edge.search";
49}
50
51impl ApiRequest for SearchCursor<'_> {
52 type Reply = SearchResult;
53 const ROUTE: &'static str = "api/edge.search";
54}
55
56#[cfg(test)]
57mod test {
58 use super::*;
59 use crate::types::Phid;
60 use phabricator_mock::task;
61 use phabricator_mock::PhabMockServer;
62
63 #[tokio::test]
64 async fn simple() {
65 let m = PhabMockServer::start().await;
66 let user = m.new_user("user", "Test User");
67 let t100 = m.new_simple_task(100, &user);
68 let t200 = m.new_simple_task(200, &user);
69
70 task::link(&t100, &t200);
71
72 let client = crate::Client::new(m.uri(), m.token().to_string());
73 let s = Search {
74 sources: vec![Phid(t100.phid.to_string())],
75 types: vec![Type::TaskSubtask],
76 ..Default::default()
77 };
78
79 let r = client.request(&s).await.unwrap();
80 assert_eq!(r.data.len(), 1);
81 assert_eq!(t100.phid, r.data[0].source.0.as_str());
82 assert_eq!(t200.phid, r.data[0].dest.0.as_str());
83 assert_eq!(Type::TaskSubtask, r.data[0].ty);
84
85 let s = Search {
86 sources: vec![Phid(t200.phid.to_string())],
87 types: vec![Type::TaskParent],
88 ..Default::default()
89 };
90
91 let r = client.request(&s).await.unwrap();
92 assert_eq!(r.data.len(), 1);
93 assert_eq!(t200.phid, r.data[0].source.0.as_str());
94 assert_eq!(t100.phid, r.data[0].dest.0.as_str());
95 assert_eq!(Type::TaskParent, r.data[0].ty);
96 }
97}