use std::prelude::v1::*;
use crate::ToParams;
use crate::Error;
use std::str::FromStr;
#[repr(transparent)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AppId(String);
#[repr(transparent)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AppKey(String);
#[repr(transparent)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UserKey(String);
#[repr(transparent)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OAuthToken(String);
impl AsRef<str> for AppId {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
impl AsRef<str> for AppKey {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
impl AsRef<str> for UserKey {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
impl AsRef<str> for OAuthToken {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
impl FromStr for AppId {
type Err = Error;
fn from_str(s: &str) -> Result<AppId, Self::Err> {
Ok(AppId(s.into()))
}
}
impl FromStr for AppKey {
type Err = Error;
fn from_str(s: &str) -> Result<AppKey, Self::Err> {
Ok(AppKey(s.into()))
}
}
impl FromStr for UserKey {
type Err = Error;
fn from_str(s: &str) -> Result<UserKey, Self::Err> {
Ok(UserKey(s.into()))
}
}
impl FromStr for OAuthToken {
type Err = Error;
fn from_str(s: &str) -> Result<OAuthToken, Self::Err> {
Ok(OAuthToken(s.into()))
}
}
impl<'a> From<&'a str> for AppId
where
Self: FromStr,
{
fn from(s: &'a str) -> AppId {
s.parse().unwrap()
}
}
impl<'a> From<&'a str> for AppKey
where
Self: FromStr,
{
fn from(s: &'a str) -> AppKey {
s.parse().unwrap()
}
}
impl<'a> From<&'a str> for UserKey
where
Self: FromStr,
{
fn from(s: &'a str) -> UserKey {
s.parse().unwrap()
}
}
impl<'a> From<&'a str> for OAuthToken
where
Self: FromStr,
{
fn from(s: &'a str) -> OAuthToken {
s.parse().unwrap()
}
}
impl From<String> for AppId {
fn from(s: String) -> AppId {
AppId(s)
}
}
impl From<String> for AppKey {
fn from(s: String) -> AppKey {
AppKey(s)
}
}
impl From<String> for UserKey {
fn from(s: String) -> UserKey {
UserKey(s)
}
}
impl From<String> for OAuthToken {
fn from(s: String) -> OAuthToken {
OAuthToken(s)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Application {
AppId(AppId, Option<AppKey>),
UserKey(UserKey),
OAuthToken(OAuthToken),
}
impl From<AppId> for Application {
fn from(a: AppId) -> Self {
Application::AppId(a, None)
}
}
impl From<(AppId, AppKey)> for Application {
fn from(a: (AppId, AppKey)) -> Self {
Application::AppId(a.0, Some(a.1))
}
}
impl From<UserKey> for Application {
fn from(u: UserKey) -> Self {
Application::UserKey(u)
}
}
impl From<OAuthToken> for Application {
fn from(o: OAuthToken) -> Self {
Application::OAuthToken(o)
}
}
impl Application {
pub fn from_app_id<T: Into<AppId>>(app_id: T) -> Self {
Application::AppId(app_id.into(), None)
}
pub fn from_app_id_and_key<T: Into<AppId>, U: Into<AppKey>>(app_id: T, app_key: U) -> Self {
Application::AppId(app_id.into(), Some(app_key.into()))
}
pub fn from_user_key<T: Into<UserKey>>(user_key: T) -> Self {
Application::UserKey(user_key.into())
}
pub fn from_oauth_token<T: Into<OAuthToken>>(token: T) -> Self {
Application::OAuthToken(token.into())
}
}
use std::borrow::Cow;
impl<'k, 'v, 'this, E> ToParams<'k, 'v, 'this, E> for Application
where
'this: 'k + 'v,
E: Extend<(Cow<'k, str>, &'v str)>,
{
fn to_params_with_mangling<F: FnMut(Cow<'k, str>) -> Cow<'k, str>>(
&'this self,
extendable: &mut E,
key_mangling: &mut F,
) {
use self::Application::*;
let params = match self {
AppId(app_id, app_key_opt) => [
Some(("app_id", app_id.as_ref())),
app_key_opt
.as_ref()
.map(|app_key| ("app_key", app_key.as_ref())),
],
UserKey(user_key) => [Some(("user_key", user_key.as_ref())), None],
OAuthToken(token) => [Some(("access_token", token.as_ref())), None],
};
extendable.extend(
params
.iter()
.filter_map(|¶m| param.map(|(k, v)| (key_mangling(k.into()), v))),
);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn convert_application_from_app_id() {
let app_id = AppId::from("my_app_id");
let app = Application::from(app_id.clone());
assert_eq!(Application::AppId(app_id, None), app);
}
#[test]
fn convert_application_from_app_id_app_key() {
let app_id_key = (AppId::from("my_app_id"), AppKey::from("my_app_key"));
let app = Application::from(app_id_key.clone());
assert_eq!(Application::AppId(app_id_key.0, Some(app_id_key.1)), app);
}
#[test]
fn convert_application_from_user_key() {
let user_key = UserKey::from("my_user_key");
let app = Application::from(user_key.clone());
assert_eq!(Application::UserKey(user_key), app);
}
#[test]
fn convert_application_from_oauth_token() {
let token = OAuthToken::from("my_oauth_token");
let app = Application::from(token.clone());
assert_eq!(Application::OAuthToken(token), app);
}
#[test]
fn transforms_app_id_into_params() {
let app_id = "my_app_id";
let app = Application::from_app_id(app_id);
let mut result = Vec::new();
app.to_params(&mut result);
let expected: Vec<(Cow<str>, &str)> = vec![("app_id".into(), app_id)];
assert_eq!(expected, result);
}
#[test]
fn transforms_app_id_and_key_into_params() {
let app_id = "my_app_id";
let key = "my_key";
let app = Application::from_app_id_and_key(app_id, key);
let mut result = Vec::new();
app.to_params(&mut result);
let expected: Vec<(Cow<str>, &str)> =
vec![("app_id".into(), app_id), ("app_key".into(), key)];
assert_eq!(expected, result);
}
#[test]
fn transforms_user_key_into_params() {
let user_key = "my_user_key";
let app = Application::from_user_key(user_key);
let mut result = Vec::new();
app.to_params(&mut result);
let expected: Vec<(Cow<str>, &str)> = vec![("user_key".into(), user_key)];
assert_eq!(expected, result);
}
#[test]
fn transforms_oauth_token_into_params() {
let oauth_token = "my_token";
let app = Application::from_oauth_token(oauth_token);
let mut result = Vec::new();
app.to_params(&mut result);
let expected: Vec<(Cow<str>, &str)> = vec![("access_token".into(), oauth_token)];
assert_eq!(expected, result);
}
}