mirror of
https://github.com/alvierahman90/rabbit.git
synced 2024-12-15 02:51:59 +00:00
json serialisation
This commit is contained in:
parent
e8332ee093
commit
eebbef6782
@ -12,7 +12,10 @@ default = ["console_error_panic_hook"]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.84"
|
||||
chrono = { version = "0.4.31", features = [ "clock" ] }
|
||||
chrono = { version = "0.4.31", features = [ "clock", "serde" ] }
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
serde_json = { version = "1.0", features = [ "std" ] }
|
||||
serde_with = { version = "3.4.0", features = [ "std", "chrono_0_4", "json" ] }
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
|
37
src/db.rs
Normal file
37
src/db.rs
Normal file
@ -0,0 +1,37 @@
|
||||
pub mod json;
|
||||
|
||||
use crate::models::*;
|
||||
use std::io;
|
||||
use serde_json;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Generic(String),
|
||||
FsIo(String),
|
||||
Json(String),
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(e: io::Error) -> Self {
|
||||
Self::FsIo(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for Error {
|
||||
fn from(e: serde_json::Error) -> Self{
|
||||
Self::Json(e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Storage {
|
||||
fn add_category(&mut self, category: NewCategory) -> Result<i32, Error>;
|
||||
fn add_series(&mut self, category_id: i32, series: NewSeries) -> Result<i32, Error>;
|
||||
fn add_series_point(&mut self, category_id: i32, series_id: i32, series_point: NewSeriesPoint) -> Result<i32, Error>;
|
||||
//fn add_user(&mut self, id: i32, user: NewUser) -> Result<User, Error>;
|
||||
fn get_category(&self, id: i32) -> Option<Category>;
|
||||
//fn get_series(&self, id: i32) -> Result<Series, Error>;
|
||||
//fn get_user(&self, id: i32) -> Result<User, Error>;
|
||||
//fn update_category(&mut self, id: i32, changeset: CategoryChangeset) -> Result<(), Error>;
|
||||
//fn update_series(&mut self, id: i32, changeset: SeriesChangeset) -> Result<(), Error>;
|
||||
//fn update_user(&mut self, id: i32, changeset: UserChangeset) -> Result<(), Error>;
|
||||
}
|
136
src/db/json.rs
Normal file
136
src/db/json.rs
Normal file
@ -0,0 +1,136 @@
|
||||
use super::*;
|
||||
|
||||
pub struct JsonDb {
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
/// JsonDb is single user.
|
||||
impl JsonDb {
|
||||
pub fn new(value: Option<String>) -> Self {
|
||||
match value {
|
||||
Some(value) => JsonDb { value },
|
||||
None => JsonDb { value: String::from("[]") },
|
||||
}
|
||||
}
|
||||
|
||||
fn load(&self) -> Result<Vec<Category>, Error> {
|
||||
match serde_json::from_str::<Vec<Category>>(&self.value) {
|
||||
Ok(d) => Ok(d),
|
||||
Err(e) => Err(Error::from(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn save(&mut self, data: Vec<Category>) -> Result<(), Error> {
|
||||
let data = serde_json::to_string_pretty(&data);
|
||||
match data {
|
||||
Ok(d) => {
|
||||
self.value = d;
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => Err(Error::from(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Storage for JsonDb {
|
||||
fn add_category(&mut self, category: NewCategory) -> Result<i32, Error> {
|
||||
let mut max_id = 1;
|
||||
let mut data = self.load()?;
|
||||
for cat in data.iter().clone() {
|
||||
if cat.id > max_id {
|
||||
max_id = cat.id
|
||||
}
|
||||
}
|
||||
let created = Category::new(max_id+1, category);
|
||||
data.push(created);
|
||||
self.save(data)?;
|
||||
|
||||
Ok(max_id + 1)
|
||||
}
|
||||
|
||||
fn add_series(&mut self, category_id: i32, series: NewSeries) -> Result<i32, Error> {
|
||||
let mut max_id = 1;
|
||||
let mut cat: Option<&mut Category> = None;
|
||||
|
||||
let mut data = self.load()?;
|
||||
for cat_opt in data.iter_mut() {
|
||||
if cat_opt.id == category_id {
|
||||
cat = Some(cat_opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let None = cat {
|
||||
return Err(Error::Generic ("Unable to find category".to_owned()));
|
||||
}
|
||||
let cat = cat.unwrap();
|
||||
|
||||
|
||||
for series in cat.series.iter().clone() {
|
||||
if series.id > max_id {
|
||||
max_id = series.id;
|
||||
}
|
||||
}
|
||||
|
||||
let created = Series::new(max_id+1, series);
|
||||
cat.series.push(created);
|
||||
self.save(data)?;
|
||||
|
||||
Ok(max_id + 1)
|
||||
}
|
||||
|
||||
fn add_series_point(&mut self, category_id: i32, series_id: i32, series_point: NewSeriesPoint) -> Result<i32, Error> {
|
||||
let mut max_id = 1;
|
||||
let mut cat: Option<&mut Category> = None;
|
||||
let mut series: Option<&mut Series> = None;
|
||||
|
||||
let mut data = self.load()?;
|
||||
for cat_opt in data.iter_mut() {
|
||||
if cat_opt.id == category_id {
|
||||
cat = Some(cat_opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let None = cat {
|
||||
return Err(Error::Generic ("Unable to find category".to_owned()));
|
||||
}
|
||||
let cat = cat.unwrap();
|
||||
|
||||
for series_opt in cat.series.iter_mut() {
|
||||
if series_opt.id == series_id {
|
||||
series = Some(series_opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let None = series {
|
||||
return Err(Error::Generic ("Unable to find series".to_owned()));
|
||||
}
|
||||
let series: &mut Series = series.unwrap();
|
||||
|
||||
for point in series.points.iter().clone() {
|
||||
if point.id > max_id {
|
||||
max_id = point.id;
|
||||
}
|
||||
}
|
||||
|
||||
let created = SeriesPoint::new(max_id + 1, series_point);
|
||||
series.points.push(created);
|
||||
self.save(data)?;
|
||||
|
||||
Ok(max_id + 1)
|
||||
}
|
||||
|
||||
fn get_category(&self, id: i32) -> Option<Category> {
|
||||
let data = self.load().ok()?;
|
||||
|
||||
for cat_opt in data {
|
||||
if cat_opt.id == id {
|
||||
return Some(cat_opt);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
pub mod models;
|
||||
pub mod db;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
@ -1,9 +1,11 @@
|
||||
pub mod category;
|
||||
pub mod series;
|
||||
pub mod series_point;
|
||||
pub mod series_type;
|
||||
mod category;
|
||||
mod series;
|
||||
mod series_point;
|
||||
mod series_type;
|
||||
mod user;
|
||||
|
||||
pub use category::*;
|
||||
pub use series::*;
|
||||
pub use series_point::*;
|
||||
pub use series_type::*;
|
||||
pub use user::*;
|
||||
|
@ -1,18 +1,19 @@
|
||||
use crate::models::Series;
|
||||
use serde::{ Serialize, Deserialize };
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Category {
|
||||
id: i32,
|
||||
name: String,
|
||||
series: Vec<Series>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub series: Vec<Series>,
|
||||
}
|
||||
|
||||
impl Category {
|
||||
pub fn new(id: i32, name: String) -> Category {
|
||||
pub fn new(id: i32, new: NewCategory) -> Category {
|
||||
Category {
|
||||
id,
|
||||
name,
|
||||
series: vec![],
|
||||
name: new.name,
|
||||
series: new.series,
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,3 +21,13 @@ impl Category {
|
||||
self.series.push(series);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CategoryChangeset {
|
||||
pub name: Option<String>,
|
||||
pub series: Option<Vec<Series>>,
|
||||
}
|
||||
|
||||
pub struct NewCategory {
|
||||
pub name: String,
|
||||
pub series: Vec<Series>,
|
||||
}
|
||||
|
@ -1,23 +1,27 @@
|
||||
use chrono;
|
||||
use super::series_point::SeriesPoint;
|
||||
use serde::{ Serialize, Deserialize };
|
||||
use serde_with;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[serde_with::serde_as]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Series {
|
||||
id: i32,
|
||||
name: String,
|
||||
repeat: chrono::Duration,
|
||||
good: bool,
|
||||
points: Vec<SeriesPoint>,
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
#[serde_as(as = "serde_with::DurationSeconds<i64>")]
|
||||
pub repeat: chrono::Duration,
|
||||
pub good: bool,
|
||||
pub points: Vec<SeriesPoint>,
|
||||
}
|
||||
|
||||
impl Series {
|
||||
pub fn new(id: i32, name: String, repeat: chrono::Duration, good: bool) -> Series {
|
||||
pub fn new(id: i32, series: NewSeries) -> Series {
|
||||
Series {
|
||||
id,
|
||||
name,
|
||||
repeat,
|
||||
good,
|
||||
points: vec![],
|
||||
name: series.name,
|
||||
repeat: series.repeat,
|
||||
good: series.good,
|
||||
points: series.points,
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,3 +29,17 @@ impl Series {
|
||||
self.points.push(point);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SeriesChangeset {
|
||||
pub name: Option<String>,
|
||||
pub repeat: Option<chrono::Duration>,
|
||||
pub good: Option<bool>,
|
||||
pub points: Option<Vec<SeriesPoint>>,
|
||||
}
|
||||
|
||||
pub struct NewSeries {
|
||||
pub name: String,
|
||||
pub repeat: chrono::Duration,
|
||||
pub good: bool,
|
||||
pub points: Vec<SeriesPoint>,
|
||||
}
|
||||
|
@ -1,19 +1,25 @@
|
||||
use chrono;
|
||||
use super::series_type::SeriesType;
|
||||
use serde::{ Serialize, Deserialize };
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SeriesPoint {
|
||||
id: i32,
|
||||
timestamp: chrono::NaiveDateTime,
|
||||
value: SeriesType,
|
||||
pub id: i32,
|
||||
pub timestamp: chrono::NaiveDateTime,
|
||||
pub value: SeriesType,
|
||||
}
|
||||
|
||||
impl SeriesPoint {
|
||||
pub fn new(id: i32, timestamp: chrono::NaiveDateTime, value: SeriesType) -> SeriesPoint {
|
||||
pub fn new(id: i32, new: NewSeriesPoint) -> SeriesPoint {
|
||||
SeriesPoint {
|
||||
id,
|
||||
timestamp,
|
||||
value
|
||||
timestamp: new.timestamp,
|
||||
value: new.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NewSeriesPoint {
|
||||
pub timestamp: chrono::NaiveDateTime,
|
||||
pub value: SeriesType,
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
#[derive(Debug)]
|
||||
use serde::{ Serialize, Deserialize };
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum SeriesType {
|
||||
Bool(bool),
|
||||
Count(u32),
|
||||
|
18
src/models/user.rs
Normal file
18
src/models/user.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use serde::{ Serialize, Deserialize };
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
id: i32,
|
||||
name: String,
|
||||
email: String,
|
||||
}
|
||||
|
||||
pub struct UserChangeset {
|
||||
name: Option<String>,
|
||||
email: Option<String>,
|
||||
}
|
||||
|
||||
pub struct NewUser {
|
||||
name: String,
|
||||
email: String,
|
||||
}
|
Loading…
Reference in New Issue
Block a user