My personal-knowledge-system, with deeply integrated task tracking and long term goal planning capabilities.
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat/db: entities generated with new types

+438 -81
+1
.config/config.kdl
··· 1 1 2 2 keymap { 3 + 3 4 Home { 4 5 q Quit // Quit the application 5 6 <Ctrl-c> Quit // Another way to quit
+54 -3
Cargo.lock
··· 807 807 checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 808 808 809 809 [[package]] 810 + name = "chacha20" 811 + version = "0.10.0" 812 + source = "registry+https://github.com/rust-lang/crates.io-index" 813 + checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" 814 + dependencies = [ 815 + "cfg-if", 816 + "cpufeatures 0.3.0", 817 + "rand_core 0.10.0", 818 + ] 819 + 820 + [[package]] 810 821 name = "chrono" 811 822 version = "0.4.44" 812 823 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 995 1006 ] 996 1007 997 1008 [[package]] 1009 + name = "cpufeatures" 1010 + version = "0.3.0" 1011 + source = "registry+https://github.com/rust-lang/crates.io-index" 1012 + checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" 1013 + dependencies = [ 1014 + "libc", 1015 + ] 1016 + 1017 + [[package]] 998 1018 name = "crc" 999 1019 version = "3.4.0" 1000 1020 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1183 1203 name = "db" 1184 1204 version = "0.1.0" 1185 1205 dependencies = [ 1206 + "anyhow", 1186 1207 "migration", 1208 + "rand 0.10.0", 1187 1209 "sea-orm", 1188 1210 "thiserror 2.0.18", 1189 1211 "tokio", ··· 1744 1766 "cfg-if", 1745 1767 "libc", 1746 1768 "r-efi 6.0.0", 1769 + "rand_core 0.10.0", 1747 1770 "wasip2", 1748 1771 "wasip3", 1749 1772 ] ··· 3243 3266 version = "0.1.0" 3244 3267 dependencies = [ 3245 3268 "async-std", 3269 + "nanoid", 3270 + "sea-orm", 3246 3271 "sea-orm-migration", 3247 3272 ] 3248 3273 ··· 3275 3300 ] 3276 3301 3277 3302 [[package]] 3303 + name = "nanoid" 3304 + version = "0.4.0" 3305 + source = "registry+https://github.com/rust-lang/crates.io-index" 3306 + checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" 3307 + dependencies = [ 3308 + "rand 0.8.5", 3309 + ] 3310 + 3311 + [[package]] 3278 3312 name = "nix" 3279 3313 version = "0.29.0" 3280 3314 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3924 3958 ] 3925 3959 3926 3960 [[package]] 3961 + name = "rand" 3962 + version = "0.10.0" 3963 + source = "registry+https://github.com/rust-lang/crates.io-index" 3964 + checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" 3965 + dependencies = [ 3966 + "chacha20", 3967 + "getrandom 0.4.2", 3968 + "rand_core 0.10.0", 3969 + ] 3970 + 3971 + [[package]] 3927 3972 name = "rand_chacha" 3928 3973 version = "0.3.1" 3929 3974 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3960 4005 dependencies = [ 3961 4006 "getrandom 0.3.4", 3962 4007 ] 4008 + 4009 + [[package]] 4010 + name = "rand_core" 4011 + version = "0.10.0" 4012 + source = "registry+https://github.com/rust-lang/crates.io-index" 4013 + checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" 3963 4014 3964 4015 [[package]] 3965 4016 name = "ratatui" ··· 4510 4561 checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 4511 4562 dependencies = [ 4512 4563 "cfg-if", 4513 - "cpufeatures", 4564 + "cpufeatures 0.2.17", 4514 4565 "digest 0.10.7", 4515 4566 ] 4516 4567 ··· 4531 4582 checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" 4532 4583 dependencies = [ 4533 4584 "cfg-if", 4534 - "cpufeatures", 4585 + "cpufeatures 0.2.17", 4535 4586 "digest 0.10.7", 4536 4587 ] 4537 4588 ··· 4542 4593 checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" 4543 4594 dependencies = [ 4544 4595 "cfg-if", 4545 - "cpufeatures", 4596 + "cpufeatures 0.2.17", 4546 4597 "digest 0.11.2", 4547 4598 ] 4548 4599
+5 -1
crates/db/Cargo.toml
··· 20 20 21 21 [dev-dependencies] 22 22 tokio = {workspace = true} 23 + anyhow = "1.0.102" 24 + rand = "0.10.0" 25 + 23 26 24 27 [lints] 25 - workspace = true 28 + # a lot of autogenerated things, lints arent very useful 29 + # workspace = true
+2
crates/db/migration/Cargo.toml
··· 10 10 11 11 [dependencies] 12 12 async-std = { version = "1", features = ["attributes", "tokio1"] } 13 + nanoid = "0.4.0" 14 + sea-orm = "2.0.0-rc" 13 15 14 16 [dependencies.sea-orm-migration] 15 17 version = "2.0.0-rc"
+2
crates/db/migration/src/lib.rs
··· 1 1 pub use sea_orm_migration::prelude::*; 2 2 3 + pub mod types; 4 + 3 5 mod m20260318_233726_group_table; 4 6 mod m20260319_002245_task_table; 5 7
+14 -2
crates/db/migration/src/m20260318_233726_group_table.rs
··· 1 1 use sea_orm_migration::{prelude::*, schema::*}; 2 2 3 + use crate::types::{NANO_ID_LEN, NanoId, Priority}; 4 + 3 5 #[derive(DeriveMigrationName)] 4 6 pub struct Migration; 5 7 ··· 12 14 .table(Group::Table) 13 15 .if_not_exists() 14 16 .col(pk_auto(Group::Id)) 15 - .col(string(Group::NanoId).unique_key().not_null()) 17 + .col( 18 + string(Group::NanoId) 19 + .string_len(NANO_ID_LEN as u32) 20 + .unique_key() 21 + .not_null() 22 + .default(NanoId::default().0), 23 + ) 16 24 .col(string(Group::Name).not_null()) 17 25 //Note: Color is a hex color with the leading # 18 26 .col(string(Group::Color).not_null()) 19 27 .col(string(Group::DescriptionPath).not_null()) 20 - .col(integer(Group::Priority).not_null().default(0)) 28 + .col( 29 + string(Group::Priority) 30 + .not_null() 31 + .default(Priority::default().to_string()), 32 + ) 21 33 .col(timestamp(Group::CreatedAt).default(Expr::current_timestamp())) 22 34 .col(timestamp(Group::ModifiedAt).default(Expr::current_timestamp())) 23 35 .col(string_null(Group::ParentGroupId))
+17 -4
crates/db/migration/src/m20260319_002245_task_table.rs
··· 1 1 use sea_orm_migration::{prelude::*, schema::*}; 2 2 3 - use crate::m20260318_233726_group_table::Group; 3 + use crate::{ 4 + m20260318_233726_group_table::Group, 5 + types::{NANO_ID_LEN, NanoId, Priority}, 6 + }; 4 7 5 8 #[derive(DeriveMigrationName)] 6 9 pub struct Migration; ··· 14 17 .table(Task::Table) 15 18 .if_not_exists() 16 19 .col(pk_auto(Task::Id)) 17 - .col(string(Task::NanoId).unique_key().not_null()) 20 + .col( 21 + string(Task::NanoId) 22 + .string_len(NANO_ID_LEN as u32) 23 + .unique_key() 24 + .not_null() 25 + .default(NanoId::default().0), 26 + ) 18 27 .col(string(Task::Name).not_null()) 19 28 .col(string(Task::DescriptionPath).not_null()) 20 - .col(integer(Task::Priority).not_null().default(0)) 29 + .col( 30 + string(Task::Priority) 31 + .not_null() 32 + .default(Priority::default().to_string()), 33 + ) 21 34 .col(timestamp(Task::Due).null()) 22 35 .col(timestamp(Task::CreatedAt).default(Expr::current_timestamp())) 23 36 .col(timestamp(Task::ModifiedAt).default(Expr::current_timestamp())) 24 - .col(string_null(Task::GroupId)) 37 + .col(string(Task::GroupId).not_null()) 25 38 .foreign_key( 26 39 ForeignKey::create() 27 40 .name("fk_task_group_id") // unique constraint name
+6
crates/db/migration/src/types/mod.rs
··· 1 + mod priority; 2 + pub use priority::Priority; 3 + 4 + mod nano_id; 5 + pub(crate) use nano_id::NANO_ID_LEN; 6 + pub use nano_id::NanoId;
+46
crates/db/migration/src/types/nano_id.rs
··· 1 + use nanoid::nanoid; 2 + use sea_orm::DeriveValueType; 3 + 4 + #[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)] 5 + #[sea_orm(value_type = "String")] 6 + pub struct NanoId(pub(crate) String); 7 + 8 + const ALPHABET: [char; 26] = [ 9 + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 10 + 't', 'u', 'v', 'w', 'x', 'y', 'z', 11 + ]; 12 + 13 + pub const NANO_ID_LEN: usize = 6; 14 + 15 + impl Default for NanoId { 16 + fn default() -> Self { 17 + Self(nanoid!(NANO_ID_LEN, &ALPHABET)) 18 + } 19 + } 20 + 21 + #[derive(Debug)] 22 + pub struct NanoIdParseError { 23 + bad: String, 24 + } 25 + 26 + impl std::error::Error for NanoIdParseError {} 27 + 28 + impl std::fmt::Display for NanoIdParseError { 29 + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 30 + write!(f, "{} is not a valid NanoId!", self.bad) 31 + } 32 + } 33 + 34 + impl std::fmt::Display for NanoId { 35 + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 36 + write!(f, "{}", self.0) 37 + } 38 + } 39 + 40 + impl std::str::FromStr for NanoId { 41 + type Err = NanoIdParseError; 42 + 43 + fn from_str(s: &str) -> Result<Self, Self::Err> { 44 + Ok(Self(s.to_owned())) 45 + } 46 + }
+56
crates/db/migration/src/types/priority.rs
··· 1 + use sea_orm::DeriveValueType; 2 + 3 + #[derive(Clone, Debug, PartialEq, Eq, DeriveValueType, Default)] 4 + #[sea_orm(value_type = "String")] 5 + pub enum Priority { 6 + Asap, 7 + High, 8 + #[default] 9 + Medium, 10 + Low, 11 + Far, 12 + } 13 + 14 + #[derive(Debug)] 15 + pub struct PriorityParseError { 16 + bad: String, 17 + } 18 + 19 + impl std::error::Error for PriorityParseError {} 20 + 21 + impl std::fmt::Display for PriorityParseError { 22 + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 23 + write!(f, "{} is not a valid Priority!", self.bad) 24 + } 25 + } 26 + 27 + impl std::fmt::Display for Priority { 28 + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 29 + let str = match self { 30 + Priority::Asap => "ASAP", 31 + Priority::High => "High", 32 + Priority::Medium => "Medium", 33 + Priority::Low => "Low", 34 + Priority::Far => "Far", 35 + }; 36 + 37 + write!(f, "{str}") 38 + } 39 + } 40 + 41 + impl std::str::FromStr for Priority { 42 + type Err = PriorityParseError; 43 + 44 + fn from_str(s: &str) -> Result<Self, Self::Err> { 45 + let v = match s { 46 + "ASAP" => Self::Asap, 47 + "High" => Self::High, 48 + "Medium" => Priority::Medium, 49 + "Low" => Self::Low, 50 + "Far" => Self::Far, 51 + _ => return Err(PriorityParseError { bad: s.to_owned() }), 52 + }; 53 + 54 + Ok(v) 55 + } 56 + }
+15 -22
crates/db/src/entity/group.rs
··· 1 - //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 1 + //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 2 2 3 3 use sea_orm::entity::prelude::*; 4 + use migration::types::*; 4 5 5 - #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] 6 + #[sea_orm::model] 7 + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] 6 8 #[sea_orm(table_name = "group")] 7 9 pub struct Model { 8 10 #[sea_orm(primary_key)] 9 - pub id: i32, 11 + pub id: i64, 10 12 #[sea_orm(unique)] 11 - pub nano_id: String, 13 + pub nano_id: NanoId, 12 14 pub name: String, 13 15 pub color: String, 14 16 pub description_path: String, 15 - pub priority: i32, 17 + pub priority: Priority, 16 18 pub created_at: DateTimeUtc, 17 19 pub modified_at: DateTimeUtc, 18 - pub parent_group_id: Option<String>, 19 - } 20 - 21 - #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] 22 - pub enum Relation { 20 + pub parent_group_id: Option<NanoId>, 23 21 #[sea_orm( 24 - belongs_to = "Entity", 25 - from = "Column::ParentGroupId", 26 - to = "Column::NanoId", 22 + self_ref, 23 + relation_enum = "SelfRef", 24 + from = "parent_group_id", 25 + to = "nano_id", 27 26 on_update = "Cascade", 28 27 on_delete = "Cascade" 29 28 )] 30 - SelfRef, 31 - #[sea_orm(has_many = "super::task::Entity")] 32 - Task, 33 - } 34 - 35 - impl Related<super::task::Entity> for Entity { 36 - fn to() -> RelationDef { 37 - Relation::Task.def() 38 - } 29 + pub group: HasOne<Entity>, 30 + #[sea_orm(has_many)] 31 + pub tasks: HasMany<super::task::Entity>, 39 32 } 40 33 41 34 impl ActiveModelBehavior for ActiveModel {}
+1 -1
crates/db/src/entity/mod.rs
··· 1 - //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 1 + //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 2 2 3 3 pub mod prelude; 4 4
+1 -1
crates/db/src/entity/prelude.rs
··· 1 - //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 1 + //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 2 2 3 3 pub use super::group::Entity as Group; 4 4 pub use super::task::Entity as Task;
+12 -20
crates/db/src/entity/task.rs
··· 1 - //! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 1 + //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 2 2 3 + use migration::types::*; 3 4 use sea_orm::entity::prelude::*; 4 5 5 - #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] 6 + #[sea_orm::model] 7 + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] 6 8 #[sea_orm(table_name = "task")] 7 9 pub struct Model { 8 10 #[sea_orm(primary_key)] 9 - pub id: i32, 11 + pub id: i64, 10 12 #[sea_orm(unique)] 11 - pub nano_id: String, 13 + pub nano_id: NanoId, 12 14 pub name: String, 13 15 pub description_path: String, 14 - pub priority: i32, 16 + pub priority: Priority, 15 17 pub due: Option<DateTimeUtc>, 16 18 pub created_at: DateTimeUtc, 17 19 pub modified_at: DateTimeUtc, 18 - pub group_id: Option<String>, 19 - } 20 - 21 - #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] 22 - pub enum Relation { 20 + pub group_id: NanoId, 23 21 #[sea_orm( 24 - belongs_to = "super::group::Entity", 25 - from = "Column::GroupId", 26 - to = "super::group::Column::NanoId", 22 + belongs_to, 23 + from = "group_id", 24 + to = "nano_id", 27 25 on_update = "Cascade", 28 26 on_delete = "Cascade" 29 27 )] 30 - Group, 31 - } 32 - 33 - impl Related<super::group::Entity> for Entity { 34 - fn to() -> RelationDef { 35 - Relation::Group.def() 36 - } 28 + pub group: HasOne<super::group::Entity>, 37 29 } 38 30 39 31 impl ActiveModelBehavior for ActiveModel {}
+20 -7
crates/db/src/lib.rs
··· 1 1 //! The database abstraction for the different actions `Filaments` requires 2 2 //! from a database service. 3 3 4 - use std::path::Path; 4 + use std::path::PathBuf; 5 5 6 6 use migration::{Migrator, MigratorTrait}; 7 7 use sea_orm::{Database, DatabaseConnection}; ··· 13 13 mod errors; 14 14 15 15 /// Database entities 16 - mod entity; 16 + pub mod entity; 17 + 18 + pub use sea_orm::ActiveValue; 17 19 18 20 #[expect(unused_imports)] 19 21 pub use errors::*; 20 22 21 23 /// Database struct 22 - #[expect(dead_code)] 23 24 #[derive(Debug)] 24 - struct Db { 25 + pub struct Db { 25 26 conn: DatabaseConnection, 26 27 } 27 28 29 + impl AsRef<DatabaseConnection> for Db { 30 + fn as_ref(&self) -> &DatabaseConnection { 31 + &self.conn 32 + } 33 + } 34 + 28 35 impl Db { 29 - async fn connect(path: &Path) -> DbResult<Self> { 30 - let connection_string = dbg! {format!( 36 + /// Connects to the database to the database at `path`. 37 + /// 38 + /// # Errors 39 + /// Will error if `path` is not a valid file. 40 + pub async fn connect(path: impl Into<PathBuf>) -> DbResult<Self> { 41 + let path = path.into(); 42 + 43 + let connection_string = format!( 31 44 "sqlite://{}", 32 45 path.canonicalize() 33 46 .map_err(|_| DbError::NotFound { 34 47 not_found_at: path.to_string_lossy().to_string() 35 48 })? 36 49 .to_string_lossy() 37 - )}; 50 + ); 38 51 39 52 debug!("connecting to {connection_string}"); 40 53
+24
crates/db/tests/common/mod.rs
··· 1 + use std::{ 2 + fs::{File, create_dir_all}, 3 + path::PathBuf, 4 + }; 5 + 6 + use db::Db; 7 + use rand::RngExt; 8 + 9 + pub async fn fresh_test_db() -> Db { 10 + let rand_id = { 11 + let mut rng = rand::rng(); 12 + let mut rand_id = [0_u8; 4]; 13 + rand_id.fill_with(|| rng.sample(rand::distr::Alphanumeric)); 14 + 15 + String::from_utf8(rand_id.to_vec()).unwrap() 16 + }; 17 + 18 + let path = PathBuf::from(format!("/tmp/filaments/test_db_{rand_id}")); 19 + 20 + create_dir_all(path.parent().unwrap()).unwrap(); 21 + 22 + let _ = File::create(&path).unwrap(); 23 + Db::connect(&path).await.unwrap() 24 + }
+48
crates/db/tests/task.rs
··· 1 + //! Testing task functionality with the database abstraction. 2 + 3 + use db::entity::{group, prelude::*}; 4 + use db::{ActiveValue::Set, entity::task}; 5 + use sea_orm::ActiveModelTrait; 6 + mod common; 7 + 8 + #[tokio::test] 9 + async fn test_group_task_insert() { 10 + let db = common::fresh_test_db().await; 11 + 12 + let group = group::ActiveModel { 13 + name: Set("something".to_owned()), 14 + color: Set("color".to_owned()), 15 + description_path: Set("something".to_owned()), 16 + ..Default::default() 17 + }; 18 + 19 + let group: group::Model = group.insert(db.as_ref()).await.unwrap(); 20 + 21 + let task = task::ActiveModel { 22 + name: Set("something".to_owned()), 23 + description_path: Set("something".to_owned()), 24 + group_id: Set(group.nano_id.to_owned()), 25 + ..Default::default() 26 + }; 27 + 28 + let task: task::Model = task.insert(db.as_ref()).await.unwrap(); 29 + 30 + let task = Task::find_by_nano_id(task.nano_id) 31 + .inner_join(Group) 32 + // .reverse_join(Group) 33 + // .find_with_related(Group) 34 + .all(db.as_ref()) 35 + .await 36 + .unwrap(); 37 + 38 + let task = Task::load() 39 + .filter_by_nano_id(task.first().unwrap().nano_id.clone()) 40 + .with(Group) 41 + .one(db.as_ref()) 42 + .await 43 + .unwrap() 44 + .unwrap(); 45 + 46 + println!("{group:#?}"); 47 + println!("{task:#?}"); 48 + }
+11 -11
flake.lock
··· 8 8 "rust-analyzer-src": "rust-analyzer-src" 9 9 }, 10 10 "locked": { 11 - "lastModified": 1773818109, 12 - "narHash": "sha256-Wsk92HrZODmCgBb+v7XfTMUAIEhqU+Obwj+09IKRTpU=", 11 + "lastModified": 1774163246, 12 + "narHash": "sha256-gzlqyLjP44LWraUd3Zn4xrQKOtK+zcBJ77pnsSUsxcM=", 13 13 "owner": "nix-community", 14 14 "repo": "fenix", 15 - "rev": "b8b443c5a1bd8dd99df899b4ac786a7f410193e5", 15 + "rev": "4cd28929c68cae521589bc21958d3793904ed1e2", 16 16 "type": "github" 17 17 }, 18 18 "original": { ··· 23 23 }, 24 24 "nixpkgs": { 25 25 "locked": { 26 - "lastModified": 1773734432, 27 - "narHash": "sha256-IF5ppUWh6gHGHYDbtVUyhwy/i7D261P7fWD1bPefOsw=", 28 - "rev": "cda48547b432e8d3b18b4180ba07473762ec8558", 29 - "revCount": 964459, 26 + "lastModified": 1773821835, 27 + "narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=", 28 + "rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0", 29 + "revCount": 964859, 30 30 "type": "tarball", 31 - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.964459%2Brev-cda48547b432e8d3b18b4180ba07473762ec8558/019cff27-f088-710d-b729-7d70ce441bc3/source.tar.gz" 31 + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.964859%2Brev-b40629efe5d6ec48dd1efba650c797ddbd39ace0/019d03e9-2959-7276-adaa-d074e96422de/source.tar.gz" 32 32 }, 33 33 "original": { 34 34 "type": "tarball", ··· 44 44 "rust-analyzer-src": { 45 45 "flake": false, 46 46 "locked": { 47 - "lastModified": 1773775226, 48 - "narHash": "sha256-413aE+fhubk1GA2v4IlRrpdZZzW/b89wJGuDfZCVtEs=", 47 + "lastModified": 1774097238, 48 + "narHash": "sha256-hcujm/qEX4RUybdBCrQKdQNqTRYDItmnbjJRP5ky5vc=", 49 49 "owner": "rust-lang", 50 50 "repo": "rust-analyzer", 51 - "rev": "4eac290b58a70961e78f2e0c04f61a08b995b2cb", 51 + "rev": "76de1de27c0ca1329bc41324edab22c82d69e779", 52 52 "type": "github" 53 53 }, 54 54 "original": {
+24
flake.nix
··· 43 43 { 44 44 45 45 overlays.default = final: prev: { 46 + 47 + sea-orm-cli = final.rustPlatform.buildRustPackage rec { 48 + pname = "sea-orm-cli"; 49 + version = "2.0.0-rc.37"; 50 + 51 + src = final.fetchCrate { 52 + inherit pname version; 53 + 54 + sha256 = "sha256-YbP85rVO41S7ZPWSpVz3jICLAEU8H/a2axJBtdFRuWY="; 55 + 56 + }; 57 + 58 + cargoHash = "sha256-6lOXyaNxrIfCI3T9nIPR76rhQXvRzSVQUsPRjo5abmI="; 59 + 60 + nativeBuildInputs = [ final.pkg-config ]; 61 + 62 + buildInputs = [ 63 + final.openssl 64 + ]; 65 + 66 + doCheck = false; # Skip tests to speed up the build 67 + }; 68 + 46 69 rustToolchain = 47 70 with inputs.fenix.packages.${prev.stdenv.hostPlatform.system}; 48 71 combine ( ··· 72 95 cargo-edit 73 96 cargo-watch 74 97 rust-analyzer 98 + 75 99 sea-orm-cli 76 100 77 101 bacon
+25 -5
justfile
··· 22 22 23 23 24 24 # Only used to build / generate entities 25 - dev-db := "sqlite:///" + justfile_directory() + "/target/dev.db" 25 + dev-db := justfile_directory() + "/target/dev.db" 26 + dev-db-url := "sqlite:///" + dev-db 26 27 27 28 # build entities from migrations 28 29 [working-directory:"crates/db"] 29 30 entity: 30 - touch ../../target/dev.db 31 - cd migration && cargo run -- -u {{dev-db}} 31 + # create the dev db 32 + rm -f {{dev-db}} 33 + touch {{dev-db}} 34 + 35 + # run the migration 36 + cd migration && cargo run -- -u {{dev-db-url}} 37 + 38 + # generate entity files based off the migraiton 32 39 sea-orm-cli generate entity \ 33 - --database-url {{dev-db}} \ 40 + --database-url {{dev-db-url}} \ 34 41 --output-dir ./src/entity \ 35 - # --expanded-format # add flag if expanded format is needed for debugging 42 + --entity-format=dense # add flag if expanded format is needed for debugging 43 + 44 + # add migraton::types to every file in entity 45 + sed -i '4i use migration::types::*;' ./src/entity/*.rs 46 + 47 + # replace elementary types with specific ones 48 + sed -i 's/pub nano_id: String/pub nano_id: NanoId/g' ./src/entity/*.rs 49 + sed -i 's/pub priority: String/pub priority: Priority/g' ./src/entity/*.rs 50 + 51 + # replace parent_group_id with proper nano_id 52 + sed -i 's/pub parent_group_id: Option<String>/pub parent_group_id: Option<NanoId>/g' ./src/entity/*.rs 53 + 54 + # replace group_id with nano_id 55 + sed -i 's/pub group_id: String/pub group_id: NanoId/g' ./src/entity/*.rs 36 56 37 57 38 58
+39 -1
src/cli.rs
··· 1 - use clap::Parser; 1 + use clap::{Parser, Subcommand}; 2 2 3 3 use crate::config::{get_config_dir, get_data_dir}; 4 4 ··· 12 12 /// Frame rate, i.e. number of frames per second 13 13 #[arg(short, long, value_name = "FLOAT", default_value_t = 60.0)] 14 14 pub frame_rate: f64, 15 + 16 + #[command(subcommand)] 17 + pub command: Option<Commands>, 15 18 } 19 + 20 + #[derive(Subcommand, Debug)] 21 + pub enum Commands { 22 + /// Manage TARS groups. 23 + // #[command(subcommand)] 24 + // Group(GroupSubcommand), 25 + 26 + /// Manage TARS tasks. 27 + // #[command(subcommand)] 28 + // Task(TaskSubcommand), 29 + 30 + /// simple testing stuff 31 + Test, 32 + // Imports bulk data into TARS 33 + // NOTE: By default the importer will fill in fields with 34 + // default values if they arent present / aren't able to be 35 + // parsed properly 36 + // Import(ImportArgs), 37 + } 38 + 39 + // #[derive(Subcommand, Debug)] 40 + // /// Subcommand to manage tars groups. 41 + // pub enum GroupSubcommand { 42 + // /// Add a group. 43 + // Add(GroupAddArgs), 44 + // /// List groups. 45 + // List(GroupListArgs), 46 + // } 47 + 48 + // #[derive(Debug, Args)] 49 + // pub struct ExportArgs { 50 + // #[arg(short, long, default_value = "./tars.json")] 51 + // /// The file-path for data to pe put into. 52 + // pub out_file: PathBuf, 53 + // } 16 54 17 55 const VERSION_MESSAGE: &str = concat!( 18 56 env!("CARGO_PKG_VERSION"),
+15 -3
src/main.rs
··· 2 2 //! My (suri.codes) personal-knowledge-system, with deeply integrated task tracking and long term goal planning capabilities. 3 3 //! 4 4 5 + use crate::{app::App, cli::Cli}; 5 6 use clap::Parser; 6 - use crate::{app::App, cli::Cli}; 7 + use db::Db; 7 8 8 9 mod app; 9 10 mod cli; ··· 21 22 logging::init()?; 22 23 23 24 let args = Cli::parse(); 24 - let mut app = App::new(args.tick_rate, args.frame_rate); 25 25 26 - app.run().await?; 26 + let _db = Db::connect("/tmp/filaments/test_db.sqlite").await?; 27 + 28 + // if there is any subcommand, we want to execute that, otherwise we 29 + // just run the app 27 30 31 + if let Some(command) = args.command { 32 + match command { 33 + cli::Commands::Test => {} 34 + } 35 + } else { 36 + let mut app = App::new(args.tick_rate, args.frame_rate); 37 + 38 + app.run().await?; 39 + } 28 40 Ok(()) 29 41 }