···11use sea_orm_migration::{prelude::*, schema::*};
2233-use crate::types::{NANO_ID_LEN, NanoId, Priority};
33+use crate::{
44+ m20260323_002518_zettel_table::Zettel,
55+ types::{NANO_ID_LEN, Priority},
66+};
4758#[derive(DeriveMigrationName)]
69pub struct Migration;
···1821 string(Group::NanoId)
1922 .string_len(NANO_ID_LEN as u32)
2023 .unique_key()
2121- .not_null()
2222- .default(NanoId::default().0),
2424+ .not_null(),
2325 )
2426 .col(string(Group::Name).not_null())
2527 //Note: Color is a hex color with the leading #
2628 .col(string(Group::Color).not_null())
2727- .col(string(Group::DescriptionPath).not_null())
2829 .col(
2930 string(Group::Priority)
3031 .not_null()
···3233 )
3334 .col(timestamp(Group::CreatedAt).default(Expr::current_timestamp()))
3435 .col(timestamp(Group::ModifiedAt).default(Expr::current_timestamp()))
3636+ .col(string(Group::ZettelId).not_null().unique_key())
3737+ // foreign key for the zettel related to this group
3838+ .foreign_key(
3939+ ForeignKey::create()
4040+ .name("fk_task_zettel_id")
4141+ .from(Group::Table, Group::ZettelId)
4242+ .to(Zettel::Table, Zettel::NanoId)
4343+ .on_update(ForeignKeyAction::Cascade)
4444+ .on_delete(ForeignKeyAction::Cascade),
4545+ )
3546 .col(string_null(Group::ParentGroupId))
4747+ // foreign key for the parent group related to this group
3648 .foreign_key(
3749 ForeignKey::create()
3850 .name("fk_group_parent_id") // unique constraint name
···90102 /// Priority level of the group
91103 Priority,
921049393- /// The relative file path to the location of
9494- /// the description note for this task
9595- DescriptionPath,
105105+ /// The Id of the Zettel created for this Group
106106+ ZettelId,
9610797108 /// Creation time
98109 CreatedAt,
···11+//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0
22+#![expect(unused_imports)]
33+44+pub use super::group::Entity as Group;
55+pub use super::tag::Entity as Tag;
66+pub use super::task::Entity as Task;
77+pub use super::zettel::Entity as Zettel;
88+pub use super::zettel_tag::Entity as ZettelTag;
···11+//! The DTO's (Data Transfer Objects) used to interact with
22+//! the Database. There is also a simple database struct in here.
33+44+/// Database and its Errors
55+mod db;
66+pub use db::*;
77+88+/// exported traits for the database
99+pub use sea_orm::ActiveModelTrait;
1010+pub use sea_orm::ActiveValue;
1111+1212+/// Exporting this as a generic NanoId.
1313+pub use migration::types::NanoId;
1414+/// Exporting this as DTO so we can newtype this in a later crate
1515+/// and add additional functionality to it.
1616+pub use migration::types::Priority as PriorityDTO;
1717+1818+mod entity;
1919+2020+/// Everything related to groups.
2121+pub use entity::group::ActiveModel as GroupActiveModel;
2222+pub use entity::group::ActiveModelEx as GroupActiveModelEx;
2323+pub use entity::group::Entity as GroupEntity;
2424+pub use entity::group::Model as GroupModel;
2525+pub use entity::group::ModelEx as GroupModelEx;
2626+2727+/// Everything related to tasks.
2828+pub use entity::task::ActiveModel as TaskActiveModel;
2929+pub use entity::task::ActiveModelEx as TaskActiveModelEx;
3030+pub use entity::task::Entity as TaskEntity;
3131+pub use entity::task::Model as TaskModel;
3232+pub use entity::task::ModelEx as TaskModelEx;
3333+3434+/// Everything related to zetetl's.
3535+pub use entity::zettel::ActiveModel as ZettelActiveModel;
3636+pub use entity::zettel::ActiveModelEx as ZettelActiveModelEx;
3737+pub use entity::zettel::Entity as ZettelEntity;
3838+pub use entity::zettel::Model as ZettelModel;
3939+pub use entity::zettel::ModelEx as ZettelModelEx;
4040+4141+/// Everything related to tag's.
4242+pub use entity::tag::ActiveModel as TagActiveModel;
4343+pub use entity::tag::ActiveModelEx as TagActiveModelEx;
4444+pub use entity::tag::Entity as TagEntity;
4545+pub use entity::tag::Model as TagModel;
4646+pub use entity::tag::ModelEx as TagModelEx;
···88 /// be set as the first child as the new root `Node`.
99 ///
1010 /// ```
1111- /// use sakura::*;
1212- /// use sakura::InsertBehavior::*;
1111+ /// use tree::*;
1212+ /// use tree::InsertBehavior::*;
1313 ///
1414 /// let mut tree: Tree<i32> = Tree::new();
1515 /// let root_node = Node::new(1);
···2727 /// `Result` containing the `NodeId` of the child that was added or a `NodeIdError`
2828 ///
2929 /// ```
3030- /// use sakura::*;
3131- /// use sakura::InsertBehavior::*;
3030+ /// use tree::*;
3131+ /// use tree::InsertBehavior::*;
3232 ///
3333 /// let root_node = Node::new(1);
3434 /// let child_node = Node::new(2);
···5252 ///
5353 ///
5454 /// ```
5555- /// use sakura::*;
5656- /// use sakura::InsertBehavior::*;
5757- /// use sakura::RemoveBehavior::*;
5555+ /// use tree::*;
5656+ /// use tree::InsertBehavior::*;
5757+ /// use tree::RemoveBehavior::*;
5858 ///
5959 /// let mut tree: Tree<i32> = Tree::new();
6060 ///
···8080 /// If `A` doesn't have a parent, then this behaves exactly like
8181 /// `RemoveBehavior::OrphanChildren`.
8282 /// ```
8383- /// use sakura::*;
8484- /// use sakura::InsertBehavior::*;
8585- /// use sakura::RemoveBehavior::*;
8383+ /// use tree::*;
8484+ /// use tree::InsertBehavior::*;
8585+ /// use tree::RemoveBehavior::*;
8686 ///
8787 /// let mut tree: Tree<i32> = Tree::new();
8888 ///
···106106 /// `NodeId`'s.
107107 ///
108108 /// ```
109109- /// use sakura::*;
110110- /// use sakura::InsertBehavior::*;
111111- /// use sakura::RemoveBehavior::*;
109109+ /// use tree::*;
110110+ /// use tree::InsertBehavior::*;
111111+ /// use tree::RemoveBehavior::*;
112112 ///
113113 /// let mut tree: Tree<i32> = Tree::new();
114114 ///
···135135 /// last child of the new root `Node`.
136136 ///
137137 /// ```
138138- /// use sakura::*;
139139- /// use sakura::InsertBehavior::*;
140140- /// use sakura::MoveBehavior::*;
138138+ /// use tree::*;
139139+ /// use tree::InsertBehavior::*;
140140+ /// use tree::MoveBehavior::*;
141141 ///
142142 /// let mut tree: Tree<i32> = Tree::new();
143143 ///
···167167 /// NOTE: During the shift-up part of the above scenario, the `Node` being
168168 /// shifted up will always be added as the last child of its new parent.
169169 /// ```
170170- /// use sakura::*;
171171- /// use sakura::InsertBehavior::*;
172172- /// use sakura::MoveBehavior::*;
170170+ /// use tree::*;
171171+ /// use tree::InsertBehavior::*;
172172+ /// use tree::MoveBehavior::*;
173173 ///
174174 /// let mut tree: Tree<i32> = Tree::new();
175175 ///
···2424 /// Creates a new `Node` with the provided data
2525 ///
2626 /// ```
2727- /// use sakura::Node;
2727+ /// use tree::Node;
2828 ///
2929 /// let _one: Node<i32> = Node::new(1);
3030 /// ```
···4141 /// Returns a reference to the data inside the `Node`
4242 ///
4343 /// ```
4444- /// use sakura::Node;
4444+ /// use tree::Node;
4545 ///
4646 /// let x = 10;
4747 /// let node: Node<i32> = Node::new(x);
···5454 /// Returns a mutable reference to the data inside the `Node`
5555 ///
5656 /// ```
5757- /// use sakura::Node;
5757+ /// use tree::Node;
5858 ///
5959 /// let x = 10;
6060 /// let mut node: Node<i32> = Node::new(x);
···6969 /// Returns the data previously in the node
7070 ///
7171 /// ```
7272- /// use sakura::Node;
7272+ /// use tree::Node;
7373 ///
7474 /// let x = 10;
7575 /// let mut y = 15;
···8989 /// Returns the parent of this `Node`, if it has one.
9090 ///
9191 /// ```
9292- /// use sakura::Node;
9292+ /// use tree::Node;
9393 ///
9494 /// let node: Node<i32> = Node::new(1);
9595 /// # assert_eq!(node.parent(), None);
···101101 /// Returns the children of this `Node`
102102 ///
103103 /// ```
104104- /// use sakura::Node;
104104+ /// use tree::Node;
105105 ///
106106 /// let node: Node<i32> = Node::new(0);
107107 /// # assert_eq!(node.children().len(), 0);
+57-57
crates/sakura/src/tree.rs
crates/tree/src/tree.rs
···2626 /// Creates a new `TreeBuilder` with default settings.
2727 ///
2828 /// ```
2929- /// use sakura::TreeBuilder;
2929+ /// use tree::TreeBuilder;
3030 ///
3131 /// let _tree_builder: TreeBuilder<i32> = TreeBuilder::new();
3232 ///
···4444 /// Sets the root `Node` for the resulting `Tree` from this `TreeBuilder`.
4545 ///
4646 /// ```
4747- /// use sakura::TreeBuilder;
4848- /// use sakura::Node;
4747+ /// use tree::TreeBuilder;
4848+ /// use tree::Node;
4949 ///
5050 /// let _tree_builder: TreeBuilder<i32> = TreeBuilder::new().with_root(Node::new(1));
5151 /// ```
···6666 /// that your `Tree` will **contain** at **any given time**._
6767 ///
6868 /// ```
6969- /// use sakura::TreeBuilder;
6969+ /// use tree::TreeBuilder;
7070 ///
7171 /// let _tree_builder: TreeBuilder<i32> = TreeBuilder::new().with_node_capacity(1);
7272 ///
···105105 /// The maximum amount of nodes that have been removed at any given time is **3**.
106106 ///
107107 /// ```
108108- /// use sakura::TreeBuilder;
108108+ /// use tree::TreeBuilder;
109109 ///
110110 /// let _tree_builder: TreeBuilder<i32> = TreeBuilder::new().with_node_capacity(1);
111111 ///
···121121 /// Build a `Tree` based upon the current settings in the `TreeBuilder`.
122122 ///
123123 /// ```
124124- /// use sakura::TreeBuilder;
125125- /// use sakura::Tree;
126126- /// use sakura::Node;
124124+ /// use tree::TreeBuilder;
125125+ /// use tree::Tree;
126126+ /// use tree::Node;
127127 ///
128128 /// let _tree: Tree<i32> = TreeBuilder::new()
129129 /// .with_root(Node::new(5))
···154154///
155155/// # Panics
156156/// Any function that takes a `NodeId` can `panic`, but this should
157157-/// only happen with improper `NodeId` management within `Sakura`, and
157157+/// only happen with improper `NodeId` management within `tree`, and
158158/// should have nothing to do with library user's code.
159159#[derive(Debug, Serialize, Deserialize, Reconcile, Hydrate)]
160160pub struct Tree<T> {
···209209 /// Creates a new `Tree` with default settings (no root `Node` and no space pre-allocation)
210210 ///
211211 /// ```
212212- /// use sakura::Tree;
212212+ /// use tree::Tree;
213213 ///
214214 /// let _tree: Tree<i32> = Tree::new();
215215 /// ```
···231231 /// it exists. Otherwise, a `None` is returned.
232232 ///
233233 /// ```
234234- /// use sakura::*;
235235- /// use sakura::InsertBehavior::*;
234234+ /// use tree::*;
235235+ /// use tree::InsertBehavior::*;
236236 ///
237237 /// let mut tree: Tree<i32> = Tree::new();
238238 /// let root_id = tree.insert(Node::new(5), AsRoot).unwrap();
···248248 /// Returns the maximum height of the `Tree`.
249249 ///
250250 /// ```
251251- /// use sakura::*;
252252- /// use sakura::InsertBehavior::*;
251251+ /// use tree::*;
252252+ /// use tree::InsertBehavior::*;
253253 ///
254254 /// let mut tree: Tree<i32> = Tree::new();
255255 /// # assert_eq!(0, tree.height());
···285285 /// # Panics
286286 ///
287287 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
288288- /// be a bug in `Sakura`
288288+ /// be a bug in `tree`
289289 ///
290290 /// ```
291291- /// use sakura::*;
292292- /// use sakura::InsertBehavior::*;
291291+ /// use tree::*;
292292+ /// use tree::InsertBehavior::*;
293293 ///
294294 /// let mut tree: Tree<i32> = Tree::new();
295295 /// let root_id = tree.insert(Node::new(5), AsRoot).unwrap();
···324324 /// # Panics
325325 ///
326326 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
327327- /// be a bug in `Sakura`
327327+ /// be a bug in `tree`
328328 ///
329329 /// ```
330330- /// use sakura::*;
331331- /// use sakura::InsertBehavior::*;
330330+ /// use tree::*;
331331+ /// use tree::InsertBehavior::*;
332332 ///
333333 /// let mut tree: Tree<i32> = Tree::new();
334334 /// let root_id = tree.insert(Node::new(5), AsRoot).unwrap();
···363363 /// # Panics
364364 ///
365365 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
366366- /// be a bug in `Sakura`
366366+ /// be a bug in `tree`
367367 ///
368368 /// ```
369369- /// use sakura::*;
370370- /// use sakura::InsertBehavior::*;
369369+ /// use tree::*;
370370+ /// use tree::InsertBehavior::*;
371371 ///
372372 /// let root_node = Node::new(1);
373373 /// let child_node = Node::new(2);
···401401 /// # Panics
402402 ///
403403 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
404404- /// be a bug in `Sakura`
404404+ /// be a bug in `tree`
405405 ///
406406 ///
407407 /// ```
408408- /// use sakura::*;
409409- /// use sakura::InsertBehavior::*;
410410- /// use sakura::RemoveBehavior::*;
408408+ /// use tree::*;
409409+ /// use tree::InsertBehavior::*;
410410+ /// use tree::RemoveBehavior::*;
411411 ///
412412 /// let mut tree: Tree<i32> = Tree::new();
413413 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···489489 /// # Panics
490490 ///
491491 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
492492- /// be a bug in `Sakura`
492492+ /// be a bug in `tree`
493493 ///
494494 #[allow(clippy::needless_pass_by_value)]
495495 pub fn move_node(
···582582 /// # Panics
583583 ///
584584 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
585585- /// be a bug in `Sakura`
585585+ /// be a bug in `tree`
586586 ///
587587 /// ```
588588- /// use sakura::*;
589589- /// use sakura::InsertBehavior::*;
588588+ /// use tree::*;
589589+ /// use tree::InsertBehavior::*;
590590 ///
591591 /// let mut tree: Tree<i32> = Tree::new();
592592 ///
···644644 /// # Panics
645645 ///
646646 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
647647- /// be a bug in `Sakura`
647647+ /// be a bug in `tree`
648648 ///
649649 /// ```
650650- /// use sakura::*;
651651- /// use sakura::InsertBehavior::*;
650650+ /// use tree::*;
651651+ /// use tree::InsertBehavior::*;
652652 ///
653653 /// let mut tree: Tree<i32> = Tree::new();
654654 ///
···696696 /// # Panics
697697 ///
698698 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
699699- /// be a bug in `Sakura`
699699+ /// be a bug in `tree`
700700 ///
701701 /// ```
702702- /// use sakura::*;
703703- /// use sakura::InsertBehavior::*;
702702+ /// use tree::*;
703703+ /// use tree::InsertBehavior::*;
704704 ///
705705 /// let mut tree: Tree<i32> = Tree::new();
706706 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···726726 /// # Panics
727727 ///
728728 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
729729- /// be a bug in `Sakura`
729729+ /// be a bug in `tree`
730730 ///
731731 ///
732732 /// ```
733733- /// use sakura::*;
734734- /// use sakura::InsertBehavior::*;
733733+ /// use tree::*;
734734+ /// use tree::InsertBehavior::*;
735735 ///
736736 /// let mut tree: Tree<i32> = Tree::new();
737737 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···758758 /// # Panics
759759 ///
760760 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
761761- /// be a bug in `Sakura`
761761+ /// be a bug in `tree`
762762 ///
763763 /// ```
764764- /// use sakura::*;
765765- /// use sakura::InsertBehavior::*;
764764+ /// use tree::*;
765765+ /// use tree::InsertBehavior::*;
766766 ///
767767 /// let mut tree: Tree<i32> = Tree::new();
768768 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···787787 /// # Panics
788788 ///
789789 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
790790- /// be a bug in `Sakura`
790790+ /// be a bug in `tree`
791791 ///
792792 /// ```
793793- /// use sakura::*;
794794- /// use sakura::InsertBehavior::*;
793793+ /// use tree::*;
794794+ /// use tree::InsertBehavior::*;
795795 ///
796796 /// let mut tree: Tree<i32> = Tree::new();
797797 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···816816 /// # Panics
817817 ///
818818 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
819819- /// be a bug in `Sakura`
819819+ /// be a bug in `tree`
820820 ///
821821 /// ```
822822- /// use sakura::*;
823823- /// use sakura::InsertBehavior::*;
822822+ /// use tree::*;
823823+ /// use tree::InsertBehavior::*;
824824 ///
825825 /// let mut tree: Tree<i32> = Tree::new();
826826 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···851851 /// # Panics
852852 ///
853853 /// Can panic if the `NodeId` does not exist in the `Tree`, but this would
854854- /// be a bug in `Sakura`
854854+ /// be a bug in `tree`
855855 ///
856856 /// ```
857857- /// use sakura::*;
858858- /// use sakura::InsertBehavior::*;
857857+ /// use tree::*;
858858+ /// use tree::InsertBehavior::*;
859859 ///
860860 /// let mut tree: Tree<i32> = Tree::new();
861861 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···971971 assert!(
972972 idx <= self.nodes.len(),
973973 "NodeId: {node_id:?} is out of bounds. This is a bug inside
974974- Sakura.",
974974+ tree.",
975975 );
976976977977 if self.nodes.get(idx).is_none() {
···10631063 /// Function can error if something goes wrong during debug!
10641064 ///
10651065 /// ```
10661066- /// use sakura::Tree;
10671067- /// use sakura::Node;
10681068- /// use sakura::InsertBehavior::*;
10661066+ /// use tree::Tree;
10671067+ /// use tree::Node;
10681068+ /// use tree::InsertBehavior::*;
10691069 ///
10701070 /// let mut tree = Tree::<i32>::new();
10711071 /// let root_id = tree.insert(Node::new(0), AsRoot).unwrap();
···10851085 /// Writes nothing if the tree is empty.
10861086 ///
10871087 /// ```
10881088- /// use sakura::Tree;
10881088+ /// use tree::Tree;
10891089 ///
10901090 /// let tree = Tree::<i32>::new();
10911091 /// let mut s = String::new();
···2233use crate::config::{get_config_dir, get_data_dir};
4455+mod process;
66+57#[derive(Parser, Debug)]
68#[command(author, version = version(), about)]
79pub struct Cli {
···19212022#[derive(Subcommand, Debug)]
2123pub enum Commands {
2222- /// Manage TARS groups.
2323- // #[command(subcommand)]
2424- // Group(GroupSubcommand),
2424+ // / Manage TARS groups.
2525+ // #[command(subcommand)]
2626+ // Group(GroupSubcommand),
25272626- /// Manage TARS tasks.
2727- // #[command(subcommand)]
2828- // Task(TaskSubcommand),
2929-3030- /// simple testing stuff
3131- Test,
3232- // Imports bulk data into TARS
2828+ // / Manage TARS tasks.
2929+ // #[command(subcommand)]
3030+ // Task(TaskSubcommand),
3131+ //
3232+ //
3333+ /// Initalize Filaments.
3434+ ///
3535+ /// This will write a default config to ~/.config/filaments,
3636+ /// as well as creating a new "notebook" in the current
3737+ /// directory with the specified name. Note that we currently
3838+ /// only support one notebook.
3939+ Init {
4040+ #[arg(default_value = "ZettelKasten")]
4141+ name: String,
4242+ },
3343 // NOTE: By default the importer will fill in fields with
3444 // default values if they arent present / aren't able to be
3545 // parsed properly
+54
src/cli/process.rs
···11+use std::{
22+ env::current_dir,
33+ fs::{File, create_dir_all},
44+ io::Write,
55+};
66+77+use color_eyre::eyre::{Context, Result};
88+99+use crate::{
1010+ cli::Commands,
1111+ config::{Config, get_config_dir},
1212+};
1313+1414+impl Commands {
1515+ pub fn process(self) -> Result<()> {
1616+ match self {
1717+ Self::Init { name } => {
1818+ // create the directory
1919+ let dir = current_dir()
2020+ .context("Failed to get current directory")?
2121+ .join(&name);
2222+2323+ // create the .filaments folder
2424+ let filaments_dir = dir.join(".filaments");
2525+2626+ create_dir_all(&filaments_dir)
2727+ .context("Failed to create the filaments directory!")?;
2828+2929+ // create the database inside there
3030+ File::create(filaments_dir.join("filaments.db"))?;
3131+3232+ // write config that sets the filaments directory to current dir!
3333+ let config_kdl = dbg! {Config::generate(&dir)};
3434+3535+ // create the config dir
3636+ let config_dir = get_config_dir();
3737+3838+ create_dir_all(config_dir).expect("creating the config dir should not error");
3939+4040+ let mut config_file = File::create(get_config_dir().join("config.kdl"))
4141+ .context("Failed to create config file")?;
4242+4343+ write!(config_file, "{config_kdl}")?;
4444+4545+ println!("wrote config to {config_file:#?}");
4646+4747+ // report status!
4848+ println!("Initialized successfully!");
4949+ }
5050+ }
5151+5252+ Ok(())
5353+ }
5454+}
+76-17
src/config.rs
···11+use color_eyre::eyre::Context;
12use directories::ProjectDirs;
23use kdl::KdlDocument;
34use serde::Deserialize;
44-use std::{env, path::PathBuf, sync::LazyLock};
55+use std::{
66+ env::{self, home_dir},
77+ fmt::Debug,
88+ fs::File,
99+ io::Read,
1010+ path::{Path, PathBuf},
1111+ sync::LazyLock,
1212+};
513614use crate::keymap::KeyMap;
715···2937#[derive(Clone, Debug, Deserialize, Default)]
3038#[expect(dead_code)]
3139pub struct AppConfig {
4040+ /// The directory where the single instance of the filaments exists.
4141+ pub filaments: PathBuf,
3242 #[serde(default)]
3333- pub data_dir: PathBuf,
4343+ pub data: PathBuf,
3444 #[serde(default)]
3535- pub config_dir: PathBuf,
4545+ pub config: PathBuf,
3646}
37473848/// Configuration for the App
···4555}
46564757impl Config {
4848- pub fn new() -> Self {
4949- let default_config: KdlDocument = DEFAULT_CONFIG
5858+ /// generates a new config with the provided `filaments_dir`
5959+ pub fn generate(filaments_dir: &Path) -> KdlDocument {
6060+ let mut default_config: KdlDocument = DEFAULT_CONFIG
5061 .parse()
5162 .expect("Default config should always be a valid KDL document.");
52635353- let keymap_node = default_config
5454- .get("keymap")
5555- .expect("Config::new Keymap must exist in default config.");
6464+ if let Some(node) = default_config
6565+ .nodes_mut()
6666+ .iter_mut()
6767+ .find(|n| n.name().value() == "filaments_dir")
6868+ && let Some(entry) = node.entries_mut().get_mut(0)
6969+ {
7070+ *entry.value_mut() = kdl::KdlValue::String(filaments_dir.to_string_lossy().to_string());
7171+ entry.clear_format();
7272+ }
7373+7474+ default_config
7575+ }
7676+7777+ /// Parse the config from `~/.config/filametns`
7878+ ///
7979+ /// # Errors
8080+ ///
8181+ /// Will error if the config doesn't exist or if there
8282+ /// is a problem parsing it.
8383+ pub fn parse() -> color_eyre::Result<Self> {
8484+ let config: KdlDocument = {
8585+ let file_path = get_config_dir().join("config.kdl");
8686+8787+ let mut file = File::open(file_path).context("Failed to find file!")?;
8888+8989+ let mut str = String::new();
9090+9191+ file.read_to_string(&mut str)
9292+ .context("Failed to read file!")?;
56935757- let keymap =
5858- KeyMap::try_from(keymap_node).expect("default config should always be a valid keymap");
9494+ str.parse().context("Expected to be valid kdl")?
9595+ };
9696+9797+ let keymap = KeyMap::try_from(
9898+ config
9999+ .get("keymap")
100100+ .expect("Keymap must exist in the config"),
101101+ )
102102+ .context("Keymap is not valid!")?;
591036060- Self {
104104+ let filaments_dir_str = config
105105+ .get("filaments_dir")
106106+ .expect("config should always have this specified")
107107+ .get(0)
108108+ .and_then(|arg| arg.as_string())
109109+ .expect("filaments_dir must be a string");
110110+111111+ let filaments_dir = PathBuf::from(filaments_dir_str)
112112+ .canonicalize()
113113+ .context("Filaments directory does not exist!")?;
114114+115115+ Ok(Self {
61116 app_config: AppConfig {
6262- data_dir: get_data_dir(),
6363- config_dir: get_config_dir(),
117117+ filaments: filaments_dir,
118118+ data: get_data_dir(),
119119+ config: get_config_dir(),
64120 },
65121 keymap,
6666- }
122122+ })
67123 }
68124}
69125···80136/// Returns the path to the OS-agnostic config directory.
81137pub fn get_config_dir() -> PathBuf {
82138 CONFIG_DIRECTORY.clone().unwrap_or_else(|| {
8383- project_directory().map_or_else(
139139+ home_dir().map_or_else(
84140 || PathBuf::from(".").join(".config"),
8585- |proj_dirs| proj_dirs.config_local_dir().to_path_buf(),
141141+ |mut path| {
142142+ path.push(".config");
143143+ path.push("filaments");
144144+ path
145145+ },
86146 )
87147 })
88148}
8989-90149fn project_directory() -> Option<ProjectDirs> {
91150 ProjectDirs::from("com", "suri-codes", env!("CARGO_PKG_NAME"))
92151}
+7-11
src/main.rs
···4455use crate::{app::App, cli::Cli};
66use clap::Parser;
77-use db::Db;
8798mod app;
109mod cli;
···23222423 let args = Cli::parse();
25242626- let _db = Db::connect("/tmp/filaments/test_db.sqlite").await?;
2727-2825 // if there is any subcommand, we want to execute that, otherwise we
2926 // just run the app
2727+ if let Some(command) = args.command {
2828+ return command.process();
2929+ }
30303131- if let Some(command) = args.command {
3232- match command {
3333- cli::Commands::Test => {}
3434- }
3535- } else {
3636- let mut app = App::new(args.tick_rate, args.frame_rate);
3131+ // if no command we run the app
3232+3333+ let mut app = App::new(args.tick_rate, args.frame_rate)?;
3434+ app.run().await?;
37353838- app.run().await?;
3939- }
4036 Ok(())
4137}