use super::{ApiLinks, ApiMeta};
use super::{HasPagination, HasResponse, HasValue};
use crate::method::{Create, Delete, Get, List};
use crate::request::Request;
use crate::request::TagRequest;
use crate::{ROOT_URL, STATIC_URL_ERROR};
use getset::{Getters, Setters};
use serde::Serialize;
use serde_json::Value;
use std::fmt::Display;
use url::Url;
const TAG_SEGMENT: &str = "tags";
const RESOURCES_SEGMENT: &str = "resources";
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
#[get = "pub"]
pub struct Tag {
name: String,
resources: Value
}
impl Tag {
pub fn create<S: AsRef<str> + Serialize + Display>(name: S) -> TagRequest<Create, Tag> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(TAG_SEGMENT);
let mut req = Request::new(url);
req.set_body(json!({
"name": name,
}));
req
}
pub fn get<S: AsRef<str> + Serialize + Display>(name: S) -> TagRequest<Get, Tag> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(TAG_SEGMENT)
.push(name.as_ref());
Request::new(url)
}
pub fn list() -> TagRequest<List, Tag> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(TAG_SEGMENT);
Request::new(url)
}
pub fn delete<S: AsRef<str> + Serialize + Display>(name: S) -> TagRequest<Delete, ()> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(TAG_SEGMENT)
.push(name.as_ref());
Request::new(url)
}
}
impl TagRequest<Get, Tag> {
pub fn add_resources<S>(mut self, resources: Vec<(S, S)>) -> TagRequest<Create, ()>
where S: AsRef<str> + Serialize + Display {
self.url_mut()
.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(RESOURCES_SEGMENT);
let resources = resources
.into_iter()
.map(|(id, kind)| {
json!({
"resource_id": id,
"resource_type": kind,
})
})
.collect::<Vec<_>>();
self.set_body(json!({
"resources": resources,
}));
self.transmute()
}
pub fn remove_resources<S>(mut self, resources: Vec<(S, S)>) -> TagRequest<Delete, ()>
where S: AsRef<str> + Serialize + Display {
self.url_mut()
.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(RESOURCES_SEGMENT);
let resources = resources
.into_iter()
.map(|(id, kind)| {
json!({
"resource_id": id,
"resource_type": kind,
})
})
.collect::<Vec<_>>();
self.set_body(json!({
"resources": resources,
}));
self.transmute()
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TagResponse {
tag: Tag
}
impl HasValue for TagResponse {
type Value = Tag;
fn value(self) -> Tag {
self.tag
}
}
impl HasResponse for Tag {
type Response = TagResponse;
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TagListResponse {
tags: Vec<Tag>,
links: ApiLinks,
meta: ApiMeta
}
impl HasResponse for Vec<Tag> {
type Response = TagListResponse;
}
impl HasPagination for TagListResponse {
fn next_page(&self) -> Option<Url> {
self.links.next()
}
}
impl HasValue for TagListResponse {
type Value = Vec<Tag>;
fn value(self) -> Vec<Tag> {
self.tags
}
}