#![warn(missing_docs)]
#![warn(rustdoc::broken_intra_doc_links)]
pub mod types;
pub mod requests;
pub mod error;
use std::rc::Rc;
use std::path::Path;
use std::fs::File;
use std::io::Read;
use reqwest::blocking::{Client, multipart};
use types::Node;
#[cfg(feature = "upload")]
use types::{UploadResult, Media};
use crate::requests::{
CreateAccount, EditAccountInfo, GetAccountInfo,
CreatePage, RevokeAccessToken, EditPage, GetPage,
GetPageList, GetViews, NoShortName, NoAccessToken,
NoTitle, NoContent, NoPath
};
pub use crate::error::TelegraphError;
struct MethodName {
create_account: Rc<String>,
edit_account_info: Rc<String>,
get_account_info: Rc<String>,
revoke_access_token: Rc<String>,
create_page: Rc<String>,
edit_page: Rc<String>,
get_page: Rc<String>,
get_page_list: Rc<String>,
get_views: Rc<String>
}
impl Default for MethodName{
fn default() -> Self {
MethodName {
create_account: Rc::new("https://api.telegra.ph/createAccount".to_string()),
edit_account_info: Rc::new("https://api.telegra.ph/editAccountInfo".to_string()),
get_account_info: Rc::new("https://api.telegra.ph/getAccountInfo".to_string()),
revoke_access_token: Rc::new("https://api.telegra.ph/revokeAccessToken".to_string()),
create_page: Rc::new("https://api.telegra.ph/createPage".to_string()),
edit_page: Rc::new("https://api.telegra.ph/editPage".to_string()),
get_page: Rc::new("https://api.telegra.ph/getPage".to_string()),
get_page_list: Rc::new("https://api.telegra.ph/getPageList".to_string()),
get_views: Rc::new("https://api.telegra.ph/getViews".to_string()),
}
}
}
#[derive(Default)]
pub struct Telegraph {
client: Rc<Client>,
method_name: MethodName
}
impl Telegraph {
pub fn new() -> Self {
Telegraph::default()
}
pub fn create_account(&self) -> CreateAccount<NoShortName> {
CreateAccount::new(
self.client.clone(),
self.method_name.create_account.clone()
)
}
pub fn edit_account_info(&self) -> EditAccountInfo<NoAccessToken>
{
EditAccountInfo::new(
self.client.clone(),
self.method_name.edit_account_info.clone()
)
}
pub fn get_account_info(&self) -> GetAccountInfo<NoAccessToken> {
GetAccountInfo::new(
self.client.clone(),
self.method_name.get_account_info.clone()
)
}
pub fn revoke_access_token(&self) -> RevokeAccessToken<NoAccessToken> {
RevokeAccessToken::new(
self.client.clone(),
self.method_name.revoke_access_token.clone()
)
}
pub fn create_page(&self) -> CreatePage<NoAccessToken, NoTitle, NoContent> {
CreatePage::new(
self.client.clone(),
self.method_name.create_page.clone()
)
}
pub fn edit_page(&self) -> EditPage<NoAccessToken, NoPath, NoTitle, NoContent> {
EditPage::new(
self.client.clone(),
self.method_name.edit_page.clone()
)
}
pub fn get_page(&self) -> GetPage<NoPath> {
GetPage::new(
self.client.clone(),
self.method_name.get_page.clone()
)
}
pub fn get_page_list(&self) -> GetPageList<NoAccessToken> {
GetPageList::new(
self.client.clone(),
self.method_name.get_page_list.clone()
)
}
pub fn get_views(&self) -> GetViews<NoPath> {
GetViews::new(
self.client.clone(),
self.method_name.get_views.clone()
)
}
#[cfg(feature = "upload")]
fn get_mime<T>(path: T) -> String
where T: AsRef<Path>
{
let mime = mime_guess::from_path(path).first_or(mime_guess::mime::IMAGE_JPEG);
format!("{}/{}", mime.type_(), mime.subtype())
}
#[cfg(feature = "upload")]
fn _upload<T>(client: &Client, files: &[T]) -> Result<Vec<Media>, TelegraphError>
where T: AsRef<Path>
{
let mut form = multipart::Form::new();
for (index, file_name) in files.iter().enumerate() {
let mut buf = vec![];
let mut file = File::open(file_name)?;
file.read_to_end(&mut buf)?;
let part = multipart::Part::bytes(buf)
.file_name(index.to_string())
.mime_str(&Self::get_mime(file_name))?;
form = form.part(index.to_string(), part);
}
let response = client.post("https://telegra.ph/upload")
.multipart(form)
.send()?;
match response.json::<UploadResult>()? {
UploadResult::Error { error } => Err(TelegraphError::ApiError(error)),
UploadResult::Ok(vec) => Ok(vec)
}
}
#[cfg(feature = "upload")]
pub fn upload<T>(&self, files: &[T]) -> Result<Vec<Media>, TelegraphError>
where T: AsRef<Path>
{
Self::_upload(&self.client, files)
}
#[cfg(feature = "upload")]
pub fn upload_with<T>(client: &Client, files: &[T]) -> Result<Vec<Media>, TelegraphError>
where T: AsRef<Path>
{
Self::_upload(client, files)
}
}
pub fn build_content(content: &str) -> Result<Vec<Node>, TelegraphError> {
serde_json::from_str(content).map_err(TelegraphError::from)
}