// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //! # Tree Layer //! //! This layer provides an interface between the storage layer and //! the outside world. It provides all of the basic logic, including //! the premise that a note without a parent is automatically //! made a child of the day's notepad. mod make_tree; mod structs; use nm_store::{NoteStore, NoteStoreError, NewNote}; use crate::structs::Page; use crate::make_tree::make_tree; #[derive(Debug)] pub struct Notesmachine(pub(crate) NoteStore); type Result = core::result::Result; impl Notesmachine { pub async fn new(url: &str) -> Result { let notestore = NoteStore::new(url).await?; Ok(Notesmachine(notestore)) } pub async fn get_box_via_slug(&self, slug: &str) -> Result { let (rawpage, rawnotes) = self.0.get_page_by_slug(slug).await?; Ok(make_tree(&rawpage, &rawnotes)) } pub async fn get_box(&self, title: &str) -> Result { let (rawpage, rawnotes) = self.0.get_page_by_title(title).await?; Ok(make_tree(&rawpage, &rawnotes)) } // TODO: // You should be able to: // Add a note that has no parent (gets added to "today") // Add a note that specifies only the page (gets added to page/root) // Add a note that has no position (gets tacked onto the end of the above) // Add a note that specifies the date of creation. pub async fn add_note(&self, note: &NewNote) -> Result<()> { todo!(); } pub async fn add_note_to_page(&self, note: &NewNote) -> Result<()> { todo!(); } pub async fn add_note_to_today(&self, note: &NewNote) -> Result<()> { todo!(); } pub async fn reference_note(&self, note_id: &str, new_parent_id: &str, new_position: i64) -> Result<()> { todo!(); } pub async fn embed_note(&self, note_id: &str, new_parent_id: &str, new_position: i64) -> Result<()> { todo!(); } pub async fn move_note(&self, note_id: &str, old_parent_id: &str, new_parent_id: &str, position: i64) -> Result<()> { todo!(); } pub async fn update_note(&self, note_id: &str, content: &str) -> Result<()> { todo!(); } pub async fn delete_note(&self, note_id: &str) -> Result<()> { todo!(); } } #[cfg(test)] mod tests { use super::*; use tokio; async fn fresh_inmemory_database() -> Notesmachine { let notesmachine = Notesmachine::new("sqlite://:memory:").await; assert!(notesmachine.is_ok(), "{:?}", notesmachine); let notesmachine = notesmachine.unwrap(); let reset = notesmachine.0.reset_database().await; assert!(reset.is_ok(), "{:?}", reset); notesmachine } #[tokio::test(threaded_scheduler)] async fn fetching_unfound_page_by_slug_works() { let notesmachine = fresh_inmemory_database().await; let unfoundpage = notesmachine.navigate_via_slug("nonexistent-slug").await; assert!(unfoundpage.is_err()); } #[tokio::test(threaded_scheduler)] async fn fetching_unfound_page_by_title_works() { let title = "Nonexistent Page"; let notesmachine = fresh_inmemory_database().await; let newpageresult = notesmachine.get_box(&title).await; assert!(newpageresult.is_ok(), "{:?}", newpageresult); let newpage = newpageresult.unwrap(); assert_eq!(newpage.title, title, "{:?}", newpage.title); assert_eq!(newpage.slug, "nonexistent-page", "{:?}", newpage.slug); assert_eq!(newpage.root_note.content, "", "{:?}", newpage.root_note.content); assert_eq!(newpage.root_note.notetype, "root", "{:?}", newpage.root_note.notetype); assert_eq!(newpage.root_note.children.len(), 0, "{:?}", newpage.root_note.children); } }