Maintaining External State

This section covers the state.rs module which will hold the types that we will be using to maintain non-GTK external state across the GTK UI. This will honestly be incredibly simple and short, because this iteration of the markdown editor does not have much state to be concerned about.

Planning What We Need

There are two key components that we need to be aware of throughout the lifetime of this application: the file path of the currently-active file that we are editing, and a hash sum of the file's contents to compare with the content of the current editor in order to know when we should disable/enable the save button.

ActiveMetadata

And so, the ActiveMetadata structure was born. It contains a PathBuf for storing the path of the active file, and a 64-byte hash sum that will be generated by keccak512() from the tiny-keccak crate.

# #![allow(unused_variables)]
#fn main() {
use std::path::{Path, PathBuf};
use tiny_keccak::keccak512;

pub struct ActiveMetadata {
    path: PathBuf,
    sum:  [u8; 64],
}

#}

The impl for this type will be fairly simple. We simply need a way to create a new active metadata, a means of getting a reference to the internal path, a conditional check to determine if given data computes the same sum as the internal sum, and a means of updating the internal sum for when we save a file.

# #![allow(unused_variables)]
#fn main() {
impl ActiveMetadata {
    pub fn new(path: PathBuf, data: &[u8]) -> ActiveMetadata {
        ActiveMetadata { path, sum: keccak512(data) }
    }

    pub fn get_path<'a>(&'a self) -> &'a Path { &self.path }

    pub fn get_dir(&self) -> Option<PathBuf> { self.path.parent().map(|p| p.to_path_buf()) }

    pub fn is_same_as(&self, data: &[u8]) -> bool { &keccak512(data)[..] == &self.sum[..] }

    pub fn set_sum(&mut self, data: &[u8]) { self.sum = keccak512(data); }
}

#}