Module workflow

Source
Expand description

Tp-Note’s high level API.

How to integrate this in your text editor code? First, call create_new_note_or_synchronize_filename() with the first positional command line parameter <path>. Then open the new text file with the returned path in your text editor. After modifying the text, saving it and closing your text editor, call synchronize_filename(). The returned path points to the possibly renamed note file.

Tp-Note is customizable at runtime by modifying its configuration stored in crate::config::LIB_CFG before executing the functions in this module (see type definition and documentation in crate::config::LibCfg). All functions in this API are stateless.

§Example with TemplateKind::New

use tpnote_lib::content::Content;
use tpnote_lib::content::ContentString;
use tpnote_lib::workflow::WorkflowBuilder;
use std::env::temp_dir;
use std::fs;
use std::path::Path;

// Prepare test.
let notedir = temp_dir();

let html_clipboard = ContentString::default();
let txt_clipboard = ContentString::default();
let stdin = ContentString::default();
let v = vec![&html_clipboard, &txt_clipboard, &stdin];
// This is the condition to choose: `TemplateKind::New`:
assert!(html_clipboard.is_empty() && txt_clipboard.is_empty() &&stdin.is_empty());
// There are no inhibitor rules to change the `TemplateKind`.
let template_kind_filter = |tk|tk;

// Build and run workflow.
let n = WorkflowBuilder::new(&notedir)
      // You can plug in your own type (must impl. `Content`).
     .upgrade::<ContentString, _>(
         "default", v, template_kind_filter)
     .build()
     .run()
     .unwrap();

// Check result.
assert!(n.as_os_str().to_str().unwrap()
   .contains("--Note"));
assert!(n.is_file());
let raw_note = fs::read_to_string(n).unwrap();
#[cfg(not(target_family = "windows"))]
assert!(raw_note.starts_with("\u{feff}---\ntitle:"));
#[cfg(target_family = "windows")]
assert!(raw_note.starts_with("\u{feff}---\r\ntitle:"));

The internal data storage for the note’s content is ContentString which implements the Content trait. Now we modify slightly the above example to showcase, how to overwrite one of the trait’s methods.

use std::path::Path;
use tpnote_lib::content::Content;
use tpnote_lib::content::ContentString;
use tpnote_lib::workflow::WorkflowBuilder;
use std::env::temp_dir;
use std::path::PathBuf;
use std::fs;
use std::fs::OpenOptions;
use std::io::Write;
use std::ops::Deref;

#[derive(Default, Debug, Eq, PartialEq)]
// We need a newtype because of the orphan rule.
pub struct MyContentString(ContentString);

impl AsRef<str> for MyContentString {
    fn as_ref(&self) -> &str {
        self.0.as_ref()
    }
}

impl Content for MyContentString {
    // Now we overwrite one method to show how to plugin custom code.
    fn save_as(&self, new_file_path: &Path) -> Result<(), std::io::Error> {
        let mut outfile = OpenOptions::new()
            .write(true)
            .create(true)
            .open(&new_file_path)?;
        // We do not save the content to disk, we write intstead:
        write!(outfile, "Simulation")?;
        Ok(())
   }
   // The rest we delegate.
   fn from_string(input: String, name: String) -> Self {
      MyContentString(
          ContentString::from_string(input, name))
   }
   fn header(&self) -> &str {
       self.0.header()
   }
   fn body(&self) -> &str {
       self.0.header()
   }
   fn name(&self) -> &str {
       self.0.name()
   }
}

// Prepare test.
let notedir = temp_dir();

let html_clipboard = MyContentString::default();
let txt_clipboard = MyContentString::default();
let stdin = MyContentString::default();
let v = vec![&html_clipboard, &txt_clipboard, &stdin];
// There are no inhibitor rules to change the `TemplateKind`.
let template_kind_filter = |tk|tk;

// Build and run workflow.
let n = WorkflowBuilder::new(&notedir)
      // You can plug in your own type (must impl. `Content`).
     .upgrade::<MyContentString, _>(
         "default", v, template_kind_filter)
     .build()
     .run()
     .unwrap();

// Check result.
assert!(n.as_os_str().to_str().unwrap()
   .contains("--Note"));
assert!(n.is_file());
let raw_note = fs::read_to_string(n).unwrap();
assert_eq!(raw_note, "Simulation");

Structs§

SyncFilename
In this state the workflow will only synchronize the filename.
SyncFilenameOrCreateNew
In this state the workflow will either synchronize the filename of an existing note or, -if none exists- create a new note.
Workflow
Holds the input data for the run() method.
WorkflowBuilder
Typestate of the WorkflowBuilder.