gstore 0.2.6

Global state management and easy-to-use widget macros for GTK applications written in Rust
Documentation
use serde::{Deserialize, Serialize};

pub trait HistoryState {
    fn history(&self) -> &History;
    fn set_history(&mut self, history: History);
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct History {
    history: Vec<String>,
}

impl History {
    pub fn new(default: Option<&str>) -> Self {
        History {
            history: default.map(|d| vec![d.to_string()]).unwrap_or(Vec::new()),
        }
    }

    pub fn push(&mut self, site: String) {
        self.history.push(site);
    }

    pub fn pop(&mut self) {
        self.history.pop();
    }

    pub fn latest(&self) -> Option<&String> {
        self.history.last()
    }
}

pub trait HistoryAction {
    fn navigation(&self) -> Option<&Navigation>;
    fn navigation_push(site: &str) -> Self;
    fn navigation_replace(site: &str) -> Self;
    fn navigation_go_back() -> Self;
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Navigation {
    Push(String),
    Replace(String),
    GoBack,
}

pub fn reduce_history<A, S>(action: A, state: S) -> S
where
    A: HistoryAction,
    S: Clone + HistoryState,
{
    let mut state = state.clone();
    if let Some(navigation) = action.navigation() {
        match navigation {
            Navigation::Push(site) => {
                let mut history = state.history().clone();
                history.push(site.clone());
                state.set_history(history);
            }
            Navigation::Replace(site) => {
                let mut history = Vec::new();
                history.push(site.clone());
                state.set_history(History { history });
            }
            Navigation::GoBack => {
                let mut history = state.history().clone();
                history.pop();
                state.set_history(history);
            }
        }
    }
    state
}