aboutsummaryrefslogtreecommitdiff
path: root/src/main/rust/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/rust/app.rs')
-rw-r--r--src/main/rust/app.rs205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/main/rust/app.rs b/src/main/rust/app.rs
new file mode 100644
index 0000000..d6e84e1
--- /dev/null
+++ b/src/main/rust/app.rs
@@ -0,0 +1,205 @@
+use crate::store::{Context, Store};
+use miette::{Diagnostic, Result};
+use thiserror::Error;
+
+#[derive(Default)]
+pub struct App {
+ context: Context,
+ exit: bool,
+}
+
+#[derive(Diagnostic, Debug, Error, PartialEq)]
+#[error("An overflow error occurred")]
+#[diagnostic()]
+pub struct OverflowError {
+ #[help]
+ pub _msg: String,
+}
+
+impl App {
+ /// Build context in App and pass it forward
+ pub fn init_context(&mut self) -> Result<&mut Self> {
+ let store = self.context.unwrap_store();
+
+ store.init()?;
+ Ok(self)
+ }
+
+ pub fn get_exit_status(&self) -> bool {
+ self.exit
+ }
+
+ pub fn exit(&mut self) -> Result<()> {
+ self.exit = true;
+ Ok(())
+ }
+
+ pub fn decrement_counter(&mut self) -> Result<()> {
+ let store = self.context.unwrap_store();
+ let count = store.get_counter()?;
+
+ if count == 0 {
+ Err(OverflowError {
+ _msg: "Cannot count below 0".into(),
+ }
+ .into())
+ } else {
+ store.set_counter(count - 1)?;
+ Ok(())
+ }
+ }
+
+ pub fn increment_counter(&mut self) -> Result<()> {
+ let store = self.context.unwrap_store();
+ let count = store.get_counter()?;
+
+ if count == u8::MAX {
+ Err(OverflowError {
+ _msg: "Cannot count above u8::MAX".into(),
+ }
+ .into())
+ } else {
+ store.set_counter(count + 1)?;
+ Ok(())
+ }
+ }
+
+ pub fn display_counter(&self) -> String {
+ self.context
+ .get_store()
+ .get_counter()
+ .map(|u| u.to_string())
+ .unwrap_or("Error".into())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::store::ContextError;
+
+ fn get_count(app: &App) -> Result<u8, ContextError> {
+ app.context.get_store().get_counter()
+ }
+
+ #[test]
+ fn display_counter_inited() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+
+ let count = app.display_counter();
+
+ assert_eq!(count, "0");
+ }
+
+ #[test]
+ fn display_counter_noninited() {
+ let app = App::default();
+
+ let count = app.display_counter();
+
+ assert_eq!(count, "Error");
+ }
+
+ #[test]
+ fn increment_decrement() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+
+ let res = app.increment_counter();
+ assert!(res.is_ok());
+ assert_eq!(get_count(&app).unwrap(), 1);
+
+ let res = app.decrement_counter();
+ assert!(res.is_ok());
+ assert_eq!(get_count(&app).unwrap(), 0);
+ }
+
+ #[test]
+ fn increment_n() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+ let n = 8;
+
+ for i in 1..=n {
+ let res = app.increment_counter();
+ assert!(res.is_ok());
+ assert_eq!(get_count(&app).unwrap(), i);
+ }
+ assert_eq!(get_count(&app).unwrap(), n);
+ }
+
+ #[test]
+ fn increment_n_decrement() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+ let n = 8;
+
+ for i in 1..=n {
+ let res = app.increment_counter();
+ assert!(res.is_ok());
+ assert_eq!(get_count(&app).unwrap(), i);
+ }
+ assert_eq!(get_count(&app).unwrap(), n);
+
+ let res = app.decrement_counter();
+ assert!(res.is_ok());
+ assert_eq!(get_count(&app).unwrap(), n - 1);
+ }
+
+ #[test]
+ fn exit() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+
+ let res = app.exit();
+
+ assert!(res.is_ok());
+ assert!(app.exit);
+ }
+
+ #[test]
+ fn decrement_counter_error() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+ let res = app.decrement_counter();
+
+ assert!(res.is_err());
+ let res_err = res.unwrap_err();
+ let casted_val = res_err
+ .downcast_ref::<OverflowError>()
+ .expect("something bad occurred");
+
+ let expected_err_msg: String = "Cannot count below 0".into();
+ assert_eq!(casted_val._msg, expected_err_msg);
+ assert_eq!(
+ *casted_val,
+ OverflowError {
+ _msg: expected_err_msg,
+ },
+ );
+ }
+
+ #[test]
+ fn increment_counter_error() {
+ let mut app = App::default();
+ assert!(app.init_context().is_ok());
+ assert!(app.context.unwrap_store().set_counter(u8::MAX).is_ok());
+ let res = app.increment_counter();
+
+ assert!(res.is_err());
+ let res_err = res.unwrap_err();
+ let casted_val = res_err
+ .downcast_ref::<OverflowError>()
+ .expect("something bad occurred");
+
+ let expected_err_msg: String = "Cannot count above u8::MAX".into();
+ assert_eq!(casted_val._msg, expected_err_msg);
+ assert_eq!(
+ *casted_val,
+ OverflowError {
+ _msg: expected_err_msg,
+ },
+ );
+ }
+}