Skip to content
This repository has been archived by the owner on Jun 2, 2023. It is now read-only.

Commit

Permalink
implement server channel create route
Browse files Browse the repository at this point in the history
  • Loading branch information
HTGAzureX1212 committed Jun 23, 2022
1 parent 2fadd8b commit aec1da8
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 6 deletions.
4 changes: 2 additions & 2 deletions http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ edition = "2021"
license = "ISC"
repository = "https://github.com/HarTexTeam/guilded-rs"
rust-version = "1.57.0"
version = "0.1.0-dev.6"
version = "0.1.0-dev.7"

[dependencies]
guilded_model = "0.1.0-dev.14"
guilded_validation = "0.1.0-dev.1"
guilded_validation = "0.1.0-dev.2"

hyper = { default-features = false, features = [ "client", "http1", "http2", "runtime" ], version = "0.14.19" }
hyper-rustls = { default-features = false, optional = true, features = [ "http1", "http2" ], version = "0.23.0" }
Expand Down
11 changes: 11 additions & 0 deletions http/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Duration;

use guilded_model::channel::ServerChannelType;
use guilded_validation::channel::ChannelValidationError;
use hyper::client::Client as Hyper;
use hyper::header::{HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE};
use hyper::{Body, Request as HyperRequest};
Expand All @@ -12,6 +14,7 @@ use tokio::time;
use crate::client::builder::ClientBuilder;
use crate::client::connector::Connector;
use crate::error::{Error, ErrorType};
use crate::request::server::server_channel_create::ServerChannelCreate;
use crate::request::{Method, Request};
use crate::response::future::ResponseFuture;
use crate::API_VERSION;
Expand Down Expand Up @@ -41,6 +44,14 @@ impl Client {
self.token.as_deref()
}

pub fn server_channel_create<'a>(
&'a self,
name: &'a str,
r#type: ServerChannelType,
) -> Result<ServerChannelCreate<'a>, ChannelValidationError> {
ServerChannelCreate::new(self, name, r#type)
}

pub fn request<T>(&self, request: Request) -> ResponseFuture<T> {
match self.try_request(request) {
Ok(future) => future,
Expand Down
1 change: 1 addition & 0 deletions http/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub enum ErrorType {
name: String,
},
HttpRequestBuild,
Json,
Parsing {
body: Vec<u8>,
},
Expand Down
2 changes: 2 additions & 0 deletions http/src/json.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use serde::de::DeserializeOwned;
use serde_json::Result as JsonResult;

pub use serde_json::to_vec;

pub fn from_bytes<T: DeserializeOwned>(bytes: &[u8]) -> JsonResult<T> {
serde_json::from_slice(bytes)
}
61 changes: 60 additions & 1 deletion http/src/request/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use hyper::header::HeaderValue;
use hyper::header::{HeaderName, HeaderValue};
use hyper::{HeaderMap, Method as HyperMethod};
use serde::Serialize;

use crate::error::{Error, ErrorType};
use crate::route::Route;

pub mod server;

Expand All @@ -12,6 +16,61 @@ pub struct Request {
pub(crate) use_authorization_token: bool,
}

impl Request {
pub fn builder(route: &Route<'_>) -> RequestBuilder {
RequestBuilder::new(route)
}

pub fn from_route(route: &Route<'_>) -> Self {
Self {
body: None,
headers: None,
method: route.method(),
path: route.to_string(),
use_authorization_token: true,
}
}
}

pub struct RequestBuilder(Request);

impl RequestBuilder {
pub fn new(route: &Route<'_>) -> Self {
Self(Request::from_route(route))
}

pub fn build(self) -> Request {
self.0
}

pub fn body(mut self, body: Vec<u8>) -> Self {
self.0.body = Some(body);

self
}

pub fn headers(mut self, iter: impl Iterator<Item = (HeaderName, HeaderValue)>) -> Self {
self.0.headers.replace(iter.collect());

self
}

pub fn json(self, serialize: &impl Serialize) -> Result<Self, Error> {
let bytes = crate::json::to_vec(serialize).map_err(|source| Error {
source: Some(Box::new(source)),
r#type: ErrorType::Json,
})?;

Ok(self.body(bytes))
}

pub const fn use_authorization_token(mut self, use_authorization_token: bool) -> Self {
self.0.use_authorization_token = use_authorization_token;

self
}
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum Method {
Expand Down
73 changes: 71 additions & 2 deletions http/src/request/server/server_channel_create.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
use crate::client::Client;

use guilded_model::channel::ServerChannelType;
use crate::error::Error;
use crate::request::Request;
use guilded_model::channel::{ServerChannel, ServerChannelType};
use guilded_model::id::{
marker::{CategoryMarker, GroupMarker, ServerMarker},
Id,
};
use guilded_validation::channel::{self, ChannelValidationError};
use serde::Serialize;

use crate::response::future::ResponseFuture;
use crate::route::Route;

#[must_use = "requests must be configured and executed"]
pub struct ServerChannelCreate<'a> {
client: &'a Client,
Expand All @@ -21,18 +30,78 @@ impl<'a> ServerChannelCreate<'a> {
Ok(Self {
client,
fields: ServerChannelCreateFields {
category_id: None,
group_id: None,
name,
is_public: None,
server_id: None,
topic: None,
r#type,
}
},
})
}

pub fn category_id(mut self, category_id: Id<CategoryMarker>) -> Self {
self.fields.category_id.replace(category_id);
self
}

pub fn group_id(mut self, group_id: Id<GroupMarker>) -> Self {
self.fields.group_id.replace(group_id);
self
}

pub fn is_public(mut self, is_public: bool) -> Self {
self.fields.is_public.replace(is_public);
self
}

pub fn server_id(mut self, server_id: Id<ServerMarker>) -> Self {
self.fields.server_id.replace(server_id);
self
}

pub fn topic(mut self, topic: &'a str) -> Result<Self, ChannelValidationError> {
channel::validate_topic_length(topic)?;

self.fields.topic.replace(topic);
Ok(self)
}

pub fn finish(self) -> ResponseFuture<ServerChannel> {
let client = self.client;

match self.try_into() {
Ok(request) => client.request(request),
Err(source) => ResponseFuture::error(source),
}
}
}

impl TryInto<Request> for ServerChannelCreate<'_> {
type Error = Error;

fn try_into(self) -> Result<Request, Self::Error> {
let mut request = Request::builder(&Route::ServerChannelCreate);
request = request.json(&self.fields)?;

Ok(request.build())
}
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct ServerChannelCreateFields<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
category_id: Option<Id<CategoryMarker>>,
#[serde(skip_serializing_if = "Option::is_none")]
group_id: Option<Id<GroupMarker>>,
name: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
is_public: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
server_id: Option<Id<ServerMarker>>,
#[serde(skip_serializing_if = "Option::is_none")]
topic: Option<&'a str>,
r#type: ServerChannelType,
}
2 changes: 1 addition & 1 deletion http/src/route.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! HTTP Routes of the Guilded API.
use std::fmt::{Display, Formatter, Result as FmtResult, Write};
use std::fmt::{Display, Formatter, Result as FmtResult};

use guilded_model::datetime::Timestamp;

Expand Down

0 comments on commit aec1da8

Please sign in to comment.