cfg_if::cfg_if! {
if #[cfg(feature = "hmac-sha1")] {
pub mod hmac_sha1;
pub use hmac_sha1::HmacSha1;
}
}
pub mod identity;
pub mod plaintext;
#[cfg(feature = "either")]
mod either;
pub use identity::Identity;
pub use plaintext::Plaintext;
use std::fmt::{Display, Write};
use crate::util::percent_encode;
pub trait SignatureMethod {
type Sign: Sign;
fn sign_with(self, client_secret: &str, token_secret: Option<&str>) -> Self::Sign;
}
macro_rules! provide {
($(#[doc = $doc:expr])+ $name:ident, $($rest:tt)*) => {
$(#[doc = $doc])+
fn $name<V: Display>(&mut self, value: V) {
self.parameter(concat!("oauth_", stringify!($name)), value);
}
provide! { $($rest)* }
};
($name:ident, $($rest:tt)*) => {
provide! {
#[doc = concat!(
"Feeds `self` with the `oauth_", stringify!($name), "` parameter part of the signature base string.
The default implementation forwards to the `parameter` method with `\"oauth_",
stringify!($name), "\"` as the first argument."
)]
$name, $($rest)*
}
};
() => {};
}
pub trait Sign {
type Signature: Display;
fn get_signature_method_name(&self) -> &'static str;
fn request_method(&mut self, method: &str);
fn uri<T: Display>(&mut self, uri: T);
fn parameter<V: Display>(&mut self, key: &str, value: V);
fn delimiter(&mut self);
fn end(self) -> Self::Signature;
provide! { callback, consumer_key, nonce, }
fn use_nonce(&self) -> bool {
true
}
fn signature_method(&mut self) {
self.parameter("oauth_signature_method", self.get_signature_method_name());
}
fn timestamp(&mut self, value: u64) {
self.parameter("oauth_timestamp", value);
}
fn use_timestamp(&self) -> bool {
true
}
provide! { token, verifier, }
fn version(&mut self) {
self.parameter("oauth_version", "1.0");
}
}
fn write_signing_key<W: Write>(dst: &mut W, client_secret: &str, token_secret: Option<&str>) {
write!(dst, "{}", percent_encode(client_secret)).unwrap();
dst.write_str("&").unwrap();
if let Some(ts) = token_secret {
write!(dst, "{}", percent_encode(ts)).unwrap();
}
}