diff --git a/Cargo.lock b/Cargo.lock index fea2d07..5c8d4fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3267,6 +3267,7 @@ version = "0.1.0" dependencies = [ "async-std", "nanoid", + "rgb", "sea-orm", "sea-orm-migration", ] @@ -4164,6 +4165,15 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" +dependencies = [ + "bytemuck", +] + [[package]] name = "rkyv" version = "0.7.46" diff --git a/crates/dto/migration/Cargo.toml b/crates/dto/migration/Cargo.toml index f5d4438..cc8bef7 100644 --- a/crates/dto/migration/Cargo.toml +++ b/crates/dto/migration/Cargo.toml @@ -12,6 +12,7 @@ path = "src/lib.rs" async-std = { version = "1", features = ["attributes", "tokio1"] } nanoid = "0.4.0" sea-orm = "2.0.0-rc" +rgb = "0.8.53" [dependencies.sea-orm-migration] version = "2.0.0-rc" diff --git a/crates/dto/migration/src/m20260318_233726_group_table.rs b/crates/dto/migration/src/m20260318_233726_group_table.rs index 83e4ae2..ad91067 100644 --- a/crates/dto/migration/src/m20260318_233726_group_table.rs +++ b/crates/dto/migration/src/m20260318_233726_group_table.rs @@ -25,7 +25,7 @@ impl MigrationTrait for Migration { ) .col(string(Group::Name).not_null()) //Note: Color is a hex color with the leading # - .col(string(Group::Color).not_null()) + .col(integer(Group::Color).not_null()) .col( string(Group::Priority) .not_null() diff --git a/crates/dto/migration/src/m20260327_175853_tag_table.rs b/crates/dto/migration/src/m20260327_175853_tag_table.rs index 442d583..4275e42 100644 --- a/crates/dto/migration/src/m20260327_175853_tag_table.rs +++ b/crates/dto/migration/src/m20260327_175853_tag_table.rs @@ -21,7 +21,7 @@ impl MigrationTrait for Migration { .not_null(), ) .col(string(Tag::Name).not_null()) - .col(string(Tag::Color).not_null()) + .col(integer(Tag::Color).not_null()) .to_owned(), ) .await diff --git a/crates/dto/migration/src/types/color.rs b/crates/dto/migration/src/types/color.rs new file mode 100644 index 0000000..e24bc80 --- /dev/null +++ b/crates/dto/migration/src/types/color.rs @@ -0,0 +1,51 @@ +use rgb::RGB8; +use sea_orm::DeriveValueType; +use std::fmt::{Debug, Display}; + +/// Color type +/// +/// We store it as a u32, but its actually 00000000rrrrrrrrggggggggbbbbbbbb +#[derive(Clone, Copy, PartialEq, Eq, DeriveValueType)] +pub struct Color(u32); + +impl Color { + /// create a new color + pub fn new(r: u8, g: u8, b: u8) -> Self { + Self(((r as u32) << 16) | ((g as u32) << 8) | (b as u32)) + } + + /// to convert it into a rbg8 type + pub fn to_rgb8(self) -> RGB8 { + RGB8 { + r: ((self.0 >> 16) & 0xFF) as u8, + g: ((self.0 >> 8) & 0xFF) as u8, + b: (self.0 & 0xFF) as u8, + } + } +} + +impl Debug for Color { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let rgb = self.to_rgb8(); + write!(f, "Color(#{:02X}{:02X}{:02X})", rgb.r, rgb.g, rgb.b) + } +} + +impl Display for Color { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let rgb = self.to_rgb8(); + write!(f, "#{:02X}{:02X}{:02X}", rgb.r, rgb.g, rgb.b) + } +} + +impl From for Color { + fn from(c: RGB8) -> Self { + Self::new(c.r, c.g, c.b) + } +} + +impl From for RGB8 { + fn from(c: Color) -> Self { + c.to_rgb8() + } +} diff --git a/crates/dto/migration/src/types/mod.rs b/crates/dto/migration/src/types/mod.rs index f0c74bb..6b71095 100644 --- a/crates/dto/migration/src/types/mod.rs +++ b/crates/dto/migration/src/types/mod.rs @@ -4,3 +4,6 @@ pub use priority::Priority; mod nano_id; pub(crate) use nano_id::NANO_ID_LEN; pub use nano_id::NanoId; + +mod color; +pub use color::Color; diff --git a/crates/dto/src/entity/group.rs b/crates/dto/src/entity/group.rs index d1c34cf..6750394 100644 --- a/crates/dto/src/entity/group.rs +++ b/crates/dto/src/entity/group.rs @@ -15,7 +15,7 @@ pub struct Model { #[sea_orm(unique)] pub nano_id: NanoId, pub name: String, - pub color: String, + pub color: Color, pub priority: Priority, pub created_at: DateTimeUtc, pub modified_at: DateTimeUtc, diff --git a/crates/dto/src/entity/tag.rs b/crates/dto/src/entity/tag.rs index eef5801..4d33d83 100644 --- a/crates/dto/src/entity/tag.rs +++ b/crates/dto/src/entity/tag.rs @@ -1,7 +1,8 @@ //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 use migration::types::*; -use sea_orm::{ActiveValue::Set, entity::prelude::*}; +use sea_orm::ActiveValue::Set; +use sea_orm::entity::prelude::*; use std::{future::ready, pin::Pin}; #[sea_orm::model] @@ -13,7 +14,7 @@ pub struct Model { #[sea_orm(unique)] pub nano_id: NanoId, pub name: String, - pub color: String, + pub color: Color, #[sea_orm(has_many, via = "zettel_tag")] pub zettels: HasMany, } diff --git a/crates/dto/src/entity/zettel.rs b/crates/dto/src/entity/zettel.rs index a747802..6c0cec3 100644 --- a/crates/dto/src/entity/zettel.rs +++ b/crates/dto/src/entity/zettel.rs @@ -1,7 +1,8 @@ //! `SeaORM` Entity, @generated by sea-orm-codegen 2.0 use migration::types::*; -use sea_orm::{ActiveValue::Set, entity::prelude::*}; +use sea_orm::ActiveValue::Set; +use sea_orm::entity::prelude::*; use std::{future::ready, pin::Pin}; #[sea_orm::model] diff --git a/crates/dto/src/lib.rs b/crates/dto/src/lib.rs index 77348ad..fad46eb 100644 --- a/crates/dto/src/lib.rs +++ b/crates/dto/src/lib.rs @@ -15,6 +15,11 @@ pub use migration::types::NanoId; /// and add additional functionality to it. pub use migration::types::Priority as PriorityDTO; +/// Color type, exporting as DTO because I might +/// want to newtype wrap this, might not have to, depending +/// on how I end up using it in the application. +pub use migration::types::Color as ColorDTO; + mod entity; /// Everything related to groups. diff --git a/crates/dto/tests/task.rs b/crates/dto/tests/task.rs index 202d6f6..c0a09d0 100644 --- a/crates/dto/tests/task.rs +++ b/crates/dto/tests/task.rs @@ -4,6 +4,7 @@ use dto::{ ActiveModelTrait as _, ActiveValue::Set, GroupActiveModel, GroupEntity, GroupModel, TaskActiveModel, TaskEntity, TaskModel, ZettelActiveModel, ZettelEntity, ZettelModel, }; +use migration::types::Color; mod common; #[tokio::test] @@ -21,7 +22,7 @@ async fn test_group_task_insert() { let group: GroupModel = GroupActiveModel { name: Set("something".to_owned()), - color: Set("color".to_owned()), + color: Set(Color::new(255, 0, 0)), zettel_id: Set(group_zettel.nano_id.clone()), ..Default::default() } @@ -69,4 +70,5 @@ async fn test_group_task_insert() { println!("group: {group:#?}"); println!("task: {task:#?}"); + panic!() } diff --git a/crates/dto/tests/zettel.rs b/crates/dto/tests/zettel.rs index 47841ee..b696f42 100644 --- a/crates/dto/tests/zettel.rs +++ b/crates/dto/tests/zettel.rs @@ -1,6 +1,6 @@ use dto::{ - ActiveModelTrait, ActiveValue::Set, TagActiveModel, TagEntity, TagModel, ZettelActiveModel, - ZettelEntity, ZettelModel, + ActiveModelTrait, ActiveValue::Set, ColorDTO, TagActiveModel, TagEntity, TagModel, + ZettelActiveModel, ZettelEntity, ZettelModel, }; use sea_orm::IntoActiveModel; @@ -12,7 +12,7 @@ async fn test_zettel_tag_insert() { let tag: TagModel = TagActiveModel { name: Set("Penis".to_owned()), - color: Set("Some Color".to_owned()), + color: Set(ColorDTO::new(255, 0, 0)), ..Default::default() } .insert(&*db) diff --git a/justfile b/justfile index 5a7ae7a..62c229e 100644 --- a/justfile +++ b/justfile @@ -46,6 +46,7 @@ entity: # replace elementary types with specific ones sed -i 's/pub nano_id: String/pub nano_id: NanoId/g' ./src/entity/*.rs sed -i 's/pub priority: String/pub priority: Priority/g' ./src/entity/*.rs + sed -i 's/pub color: i64/pub color: Color/g' ./src/entity/*.rs # replace parent_group_id with proper nano_id sed -i 's/pub parent_group_id: Option/pub parent_group_id: Option/g' ./src/entity/*.rs