use crate::client::NightscoutClient;
use crate::endpoints::Endpoint;
use crate::error::NightscoutError;
use crate::models::trends::Trend;
use crate::query_builder::{HasDevice, QueryBuilder};
use chrono::{DateTime, Utc};
use reqwest::Method;
use serde::{Deserialize, Serialize};
pub struct SgvService {
pub client: NightscoutClient,
}
pub struct MbgService {
pub client: NightscoutClient,
}
impl SgvService {
pub fn get(&self) -> QueryBuilder<SgvEntry> {
QueryBuilder::<SgvEntry>::new(self.client.clone(), Endpoint::Sgv, Method::GET)
.with_epoch_date_field("date")
}
pub fn delete(&self) -> QueryBuilder<SgvEntry> {
QueryBuilder::<SgvEntry>::new(self.client.clone(), Endpoint::Sgv, Method::DELETE)
.with_epoch_date_field("date")
}
pub async fn latest(&self) -> Result<SgvEntry, NightscoutError> {
let builder = self.get().limit(1);
let result = builder.send().await?;
result.first().cloned().ok_or(NightscoutError::NotFound)
}
pub async fn create(&self, entries: Vec<SgvEntry>) -> Result<Vec<SgvEntry>, NightscoutError> {
let url = self.client.base_url.join(Endpoint::Entries.as_path())?;
let mut request = self.client.http.post(url);
request = self.client.auth(request);
let response = self.client.send_checked(request.json(&entries)).await?;
Ok(response.json::<Vec<SgvEntry>>().await?)
}
}
impl MbgService {
pub fn get(&self) -> QueryBuilder<MbgEntry> {
QueryBuilder::<MbgEntry>::new(self.client.clone(), Endpoint::Mbg, Method::GET)
.with_epoch_date_field("date")
}
pub fn delete(&self) -> QueryBuilder<MbgEntry> {
QueryBuilder::<MbgEntry>::new(self.client.clone(), Endpoint::Mbg, Method::DELETE)
.with_epoch_date_field("date")
}
pub async fn latest(&self) -> Result<MbgEntry, NightscoutError> {
let builder = self.get().limit(1);
let result = builder.send().await?;
result.first().cloned().ok_or(NightscoutError::NotFound)
}
pub async fn create(&self, entries: Vec<MbgEntry>) -> Result<Vec<MbgEntry>, NightscoutError> {
let url = self.client.base_url.join(Endpoint::Entries.as_path())?;
let mut request = self.client.http.post(url);
request = self.client.auth(request);
let response = self.client.send_checked(request.json(&entries)).await?;
Ok(response.json::<Vec<MbgEntry>>().await?)
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SgvEntry {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub sgv: i32,
pub date: i64,
#[serde(
rename = "dateString",
default,
skip_serializing_if = "Option::is_none"
)]
pub date_string: Option<String>,
pub direction: Trend,
#[serde(rename = "type")]
pub type_: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub device: Option<String>,
}
impl SgvEntry {
pub fn new(sgv: i32, direction: Trend, date: DateTime<Utc>) -> Self {
SgvEntry {
id: None,
sgv,
date: date.timestamp_millis(),
date_string: Some(date.to_rfc3339()),
direction,
type_: "sgv".to_string(),
device: Some("cinnamon".to_string()),
}
}
pub fn device(mut self, name: String) -> Self {
self.device = Some(name);
self
}
pub fn datetime(&self) -> Option<DateTime<Utc>> {
DateTime::from_timestamp_millis(self.date)
}
}
impl HasDevice for SgvEntry {
fn device(&self) -> Option<&str> {
self.device.as_deref()
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MbgEntry {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub mbg: i32,
pub date: i64,
#[serde(
rename = "dateString",
default,
skip_serializing_if = "Option::is_none"
)]
pub date_string: Option<String>,
#[serde(rename = "type")]
pub type_: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub device: Option<String>,
}
impl MbgEntry {
pub fn new(mbg: i32, date: DateTime<Utc>) -> Self {
MbgEntry {
id: None,
mbg,
date: date.timestamp_millis(),
date_string: Some(date.to_rfc3339()),
type_: "mbg".to_string(),
device: Some("cinnamon".to_string()),
}
}
pub fn device(mut self, name: String) -> Self {
self.device = Some(name);
self
}
pub fn datetime(&self) -> Option<DateTime<Utc>> {
DateTime::from_timestamp_millis(self.date)
}
}
impl HasDevice for MbgEntry {
fn device(&self) -> Option<&str> {
self.device.as_deref()
}
}