diff --git a/Cargo.toml b/Cargo.toml index 6ec1a4c..bba11f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,24 @@ name = "hackaton_13-04-19" version = "0.1.0" authors = ["Aleksandrov Vladimir "] +publish = false +description = "Shared canvas on Fluence" edition = "2018" +[lib] +name = "shared_canvas" +path = "src/lib.rs" +crate-type = ["cdylib"] + +[profile.release] +debug = false +lto = true +opt-level = "z" +panic = "abort" + [dependencies] +log = "0.4" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.38" +linked-hash-map = "0.5.1" +fluence = { version = "0.1.4", features = ["wasm_logger"] } diff --git a/src/canvas_manager.rs b/src/canvas_manager.rs new file mode 100644 index 0000000..b290aa6 --- /dev/null +++ b/src/canvas_manager.rs @@ -0,0 +1,83 @@ +use crate::error_type::AppResult; +use crate::request_response::Response; + +use std::collections::hash_map::HashMap; +use std::iter; +use serde_json::Value; +use log::info; + +use crate::request_response::CellStateResponse; + +// ================== Colour ================== +#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +pub struct Colour { + r: u8, + g: u8, + b: u8 +} + +impl Colour { + pub fn new() -> Self { + Colour { + r: 0, + g: 0, + b: 0 + } + } +} + +// ================== Cell ================== + +#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +pub struct Cell { + x: u32, + y: u32 +} + +impl Cell { + pub fn new(x: u32, y: u32) -> Self { + Cell{x, y} + } +} + +// ================== CanvasManager ================== + +pub struct CanvasManager { + canvas: HashMap +} + +impl CanvasManager { + pub fn new() -> Self { + let x_size = 1000; + let y_size = 1000; + let white_colour = String::from("#ffafff"); + + let mut canvas_map: HashMap = HashMap::new(); + for x in 0..x_size { + for y in 0..y_size { + let cell = Cell::new(x, y); + canvas_map.insert(cell, white_colour.clone()); + } + } + + CanvasManager { + canvas: canvas_map + } + } + + pub fn to_response(&self) -> AppResult { + let result_state: Vec = self.canvas.iter().map(|kv| CellStateResponse::new(kv.0.x, kv.0.y, kv.1.clone())).collect(); + let result = Response::Matrix { + state:result_state + }; + + let json_response: AppResult = serde_json::to_value(result).map_err(Into::into); + + match &json_response { + Ok(res) => info!("JSON ok : {}", res.to_string()), + Err(err) => info!("JSON error: {}", err.to_string()) + } + + json_response + } +} \ No newline at end of file diff --git a/src/error_type.rs b/src/error_type.rs new file mode 100644 index 0000000..6c91888 --- /dev/null +++ b/src/error_type.rs @@ -0,0 +1,3 @@ +use std::error::Error; + +pub type AppResult = ::std::result::Result>; diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..f1dbb81 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,42 @@ +mod error_type; +mod request_response; +mod canvas_manager; + +use crate::error_type::AppResult; +use crate::canvas_manager::CanvasManager; +use crate::request_response::{Request, Response}; + +use fluence::sdk::*; +use serde_json::Value; +use std::cell::RefCell; +use log::info; + +fn init() { + logger::WasmLogger::init_with_level(log::Level::Info).unwrap(); +} + +#[invocation_handler(init_fn = init)] +fn main(req: String) -> String { + match do_request(req) { + Ok(res) => res.to_string(), + Err(err) => { + let response = Response::Error { + message: err.to_string(), + }; + serde_json::to_string(&response).unwrap() + } + } +} + +thread_local! { + static CANVAS_MANAGER: RefCell = RefCell::new(CanvasManager::new()); +} + +fn do_request(req: String) -> AppResult { + let request: Request = serde_json::from_str(req.as_str())?; + + match request { + Request::Get => CANVAS_MANAGER.with(|cm| cm.borrow_mut().to_response()), + Request::Set{x_coord, y_coord, colour} => serde_json::from_str("lala").map_err(Into::into) + } +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/src/request_response.rs b/src/request_response.rs new file mode 100644 index 0000000..d1fa04b --- /dev/null +++ b/src/request_response.rs @@ -0,0 +1,31 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +#[serde(tag = "action")] +pub enum Request { + Get, + Set { + x_coord: u32, + y_coord: u32, + colour: String + } +} + +#[derive(Serialize, Deserialize)] +#[serde(untagged)] +pub enum Response { + Matrix { state: Vec }, + PaintResult { error: Option }, + Error { message: String }, +} + +#[derive(Serialize, Deserialize)] +pub struct CellStateResponse {x: u32, y: u32, colour: String} + +impl CellStateResponse { + pub fn new(x: u32, y: u32, colour: String) -> Self { + CellStateResponse { + x, y, colour + } + } +} \ No newline at end of file