use crate::types::error;
use crate::types::SchoolListing;
use crate::types::User;
use crate::deserializers::Deserializer;
pub mod deserializers;
pub mod types;
pub mod user;
pub mod utils;
pub mod schedule;
#[derive(Debug)]
pub struct Client {
client: reqwest::Client,
base_url: String,
device_id: String,
pub user: Option<User>,
}
#[derive(Default)]
pub struct ClientBuilder {
base_url: Option<String>,
device_id: Option<String>,
}
impl Client {
pub async fn login(
&mut self,
username: &str,
password: &str,
school: &str,
) -> Result<(), error::LoginError> {
let school_url = format!("{}/{}", self.base_url, school);
let url = format!("{}/rest/app/login", school_url);
let mut params = std::collections::HashMap::new();
params.insert("identification", username);
params.insert("verification", password);
params.insert("logintype", "4");
params.insert("usertype", "1");
let request = self
.client
.request(reqwest::Method::POST, url)
.form(¶ms);
let data = utils::make_request(request)
.await
.map_err(error::LoginError::RequestError)?;
let user = User::deserialize(&data).map_err(error::LoginError::ParseError)?;
self.user = Some(user);
Ok(())
}
pub async fn schools(&self) -> Result<Vec<SchoolListing>, error::SchoolListingError> {
let url = format!("{}/rest/app/schoollist/prod", self.base_url);
let response = utils::make_request(self.client.get(&url))
.await
.map_err(error::SchoolListingError::RequestError)?;
SchoolListing::deserialize_many(&response)
}
pub fn base_url(&self) -> &str {
self.base_url.as_ref()
}
pub fn device_id(&self) -> &str {
self.device_id.as_ref()
}
}
impl ClientBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn base_url(mut self, base_url: String) -> Self {
self.base_url = Some(base_url);
self
}
pub fn device_id(mut self, device_id: String) -> Self {
self.device_id = Some(device_id);
self
}
pub fn build(self) -> Client {
Client {
client: reqwest::Client::new(),
base_url: self
.base_url
.unwrap_or("https://sms.schoolsoft.se".to_string()),
device_id: self.device_id.unwrap_or("".to_string()),
user: None,
}
}
}
#[cfg(test)]
mod client_builder_tests {
use super::*;
#[test]
fn with_base_url() {
let client = ClientBuilder::new()
.base_url("https://sms.schoolsoft.se".to_string())
.build();
assert_eq!(client.base_url(), "https://sms.schoolsoft.se");
}
}