mod vk_date_format;
mod vk_date_format_opt;
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
pub use vk_method::{Method, Params};
use async_trait::async_trait;
pub type UserId = u32;
#[async_trait]
pub trait API {
type Error: std::error::Error;
async fn method<T>(&self, method: Method) -> Result<T, Self::Error>
where for<'de>
T: serde::Deserialize<'de>;
fn users_get(&self) -> UsersGetBuilder<Self> where Self: Sized {
UsersGetBuilder::new(self)
}
fn friends_get(&self) -> FriendsGetBuilder<Self> where Self: Sized {
FriendsGetBuilder::new(self)
}
}
pub struct UsersGetBuilder<'a, A: API> {
pub user_ids: Option<Vec<String>>,
pub user_id: Option<String>,
pub fields: Option<Vec<UsersFields>>,
api: &'a A
}
impl<'a, A: API> UsersGetBuilder<'a, A> {
fn new(api: &'a A) -> Self {
UsersGetBuilder {
user_ids: None,
user_id: None,
fields: None,
api
}
}
pub fn user_id(mut self, id: impl ToString) -> Self {
self.user_id = Some(id.to_string());
self
}
pub fn user_ids(mut self, mut ids: Vec<impl ToString>) -> Self {
let mut ids = ids.iter_mut().map(|id| id.to_string()).collect();
match self.user_ids {
Some(ref mut users) => {
users.append(&mut ids)
},
None => {
self.user_ids = Some(ids);
}
}
self
}
pub fn fields(mut self, fields: Vec<UsersFields>) -> Self {
self.fields = Some(fields);
self
}
pub async fn send(self) -> Result<Vec<User>, A::Error> {
let mut params = Params::new();
if let Some(value) = self.user_id {
params.insert("user_id", value);
}
if let Some(value) = self.user_ids {
params.insert("user_id", value);
}
if let Some(value) = self.fields {
params.insert("fields", value.into_iter().map(|field| field.to_string()).collect::<Vec<String>>());
}
self.api.method(
Method::new("users.get", params)
).await
}
}
pub struct FriendsGetBuilder<'a, A: API> {
pub user_id: Option<UserId>,
pub count: Option<u16>,
api: &'a A
}
impl<'a, A: API> FriendsGetBuilder<'a, A> {
fn new(api: &'a A) -> Self {
FriendsGetBuilder {
user_id: None,
count: None,
api
}
}
pub fn user_id(mut self, id: UserId) -> Self {
self.user_id = Some(id);
self
}
pub fn count(mut self, count: u16) -> Self {
self.count = Some(count);
self
}
pub async fn send(self) -> Result<FriendsGetResponse, A::Error> {
let mut params = Params::new();
if let Some(value) = self.user_id {
params.insert("user_id", value);
}
if let Some(value) = self.count {
params.insert("count", value);
}
self.api.method(
Method::new("friends.get", params)
).await
}
}
#[derive(Serialize, Deserialize)]
pub struct FriendsGetResponse {
pub count: u16,
pub items: Vec<UserId>
}
#[allow(dead_code)]
#[derive(Deserialize, Debug, PartialEq)]
pub struct User {
pub id: UserId,
pub first_name: String,
#[serde(default)]
#[serde(with = "vk_date_format_opt")]
pub bdate: Option<NaiveDate>
}
#[derive(strum::Display)]
#[derive(Serialize)]
pub enum UsersFields {
bdate
}
#[cfg(test)]
mod tests;