digitalocean_api/api/
tag.rs1use super::{ApiLinks, ApiMeta};
2use super::{HasPagination, HasResponse, HasValue};
3use crate::method::{Create, Delete, Get, List};
4use crate::request::Request;
5use crate::request::TagRequest;
6use crate::{ROOT_URL, STATIC_URL_ERROR};
7use getset::{Getters, Setters};
8use serde::Deserialize;
9use serde::Serialize;
10use serde_json::Value;
11use std::fmt::Display;
12use url::Url;
13
14const TAG_SEGMENT: &str = "tags";
15const RESOURCES_SEGMENT: &str = "resources";
16
17#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
26#[get = "pub"]
27pub struct Tag {
28 name: String,
31
32 resources: Value,
35}
36
37impl Tag {
38 pub fn create<S: AsRef<str> + Serialize + Display>(name: S) -> TagRequest<Create, Tag> {
40 let mut url = ROOT_URL.clone();
41 url.path_segments_mut()
42 .expect(STATIC_URL_ERROR)
43 .push(TAG_SEGMENT);
44
45 let mut req = Request::new(url);
46 req.set_body(json!({
47 "name": name,
48 }));
49 req
50 }
51
52 pub fn get<S: AsRef<str> + Serialize + Display>(name: S) -> TagRequest<Get, Tag> {
54 let mut url = ROOT_URL.clone();
55 url.path_segments_mut()
56 .expect(STATIC_URL_ERROR)
57 .push(TAG_SEGMENT)
58 .push(name.as_ref());
59
60 Request::new(url)
61 }
62
63 pub fn list() -> TagRequest<List, Tag> {
65 let mut url = ROOT_URL.clone();
66 url.path_segments_mut()
67 .expect(STATIC_URL_ERROR)
68 .push(TAG_SEGMENT);
69
70 Request::new(url)
71 }
72
73 pub fn delete<S: AsRef<str> + Serialize + Display>(name: S) -> TagRequest<Delete, ()> {
75 let mut url = ROOT_URL.clone();
76 url.path_segments_mut()
77 .expect(STATIC_URL_ERROR)
78 .push(TAG_SEGMENT)
79 .push(name.as_ref());
80
81 Request::new(url)
82 }
83}
84
85impl TagRequest<Get, Tag> {
86 pub fn add_resources<S>(mut self, resources: Vec<(S, S)>) -> TagRequest<Create, ()>
90 where
91 S: AsRef<str> + Serialize + Display,
92 {
93 self.url_mut()
94 .path_segments_mut()
95 .expect(STATIC_URL_ERROR)
96 .push(RESOURCES_SEGMENT);
97
98 let resources = resources
99 .into_iter()
100 .map(|(id, kind)| {
101 json!({
102 "resource_id": id,
103 "resource_type": kind,
104 })
105 })
106 .collect::<Vec<_>>();
107
108 self.set_body(json!({
109 "resources": resources,
110 }));
111
112 self.transmute()
113 }
114
115 pub fn remove_resources<S>(mut self, resources: Vec<(S, S)>) -> TagRequest<Delete, ()>
119 where
120 S: AsRef<str> + Serialize + Display,
121 {
122 self.url_mut()
123 .path_segments_mut()
124 .expect(STATIC_URL_ERROR)
125 .push(RESOURCES_SEGMENT);
126
127 let resources = resources
128 .into_iter()
129 .map(|(id, kind)| {
130 json!({
131 "resource_id": id,
132 "resource_type": kind,
133 })
134 })
135 .collect::<Vec<_>>();
136
137 self.set_body(json!({
138 "resources": resources,
139 }));
140
141 self.transmute()
142 }
143}
144
145#[derive(Deserialize, Serialize, Debug, Clone)]
147pub struct TagResponse {
148 tag: Tag,
149}
150
151impl HasValue for TagResponse {
152 type Value = Tag;
153
154 fn value(self) -> Tag {
155 self.tag
156 }
157}
158
159impl HasResponse for Tag {
160 type Response = TagResponse;
161}
162
163#[derive(Deserialize, Serialize, Debug, Clone)]
165pub struct TagListResponse {
166 tags: Vec<Tag>,
167 links: ApiLinks,
168 meta: ApiMeta,
169}
170
171impl HasResponse for Vec<Tag> {
172 type Response = TagListResponse;
173}
174
175impl HasPagination for TagListResponse {
176 fn next_page(&self) -> Option<Url> {
177 self.links.next()
178 }
179}
180
181impl HasValue for TagListResponse {
182 type Value = Vec<Tag>;
183
184 fn value(self) -> Vec<Tag> {
185 self.tags
186 }
187}