diff --git a/crates/idfoto-core/src/item_types/card.rs b/crates/idfoto-core/src/item_types/card.rs new file mode 100644 index 0000000..481eae3 --- /dev/null +++ b/crates/idfoto-core/src/item_types/card.rs @@ -0,0 +1,15 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct CardCore {} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "snake_case")] +pub enum CardKind { + #[default] + Credit, + Debit, + Gift, + Loyalty, + Other, +} diff --git a/crates/idfoto-core/src/item_types/document.rs b/crates/idfoto-core/src/item_types/document.rs new file mode 100644 index 0000000..5a16eb4 --- /dev/null +++ b/crates/idfoto-core/src/item_types/document.rs @@ -0,0 +1,3 @@ +use serde::{Deserialize, Serialize}; +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct DocumentCore {} diff --git a/crates/idfoto-core/src/item_types/identity.rs b/crates/idfoto-core/src/item_types/identity.rs new file mode 100644 index 0000000..fa89ba2 --- /dev/null +++ b/crates/idfoto-core/src/item_types/identity.rs @@ -0,0 +1,3 @@ +use serde::{Deserialize, Serialize}; +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct IdentityCore {} diff --git a/crates/idfoto-core/src/item_types/key.rs b/crates/idfoto-core/src/item_types/key.rs new file mode 100644 index 0000000..011d1b9 --- /dev/null +++ b/crates/idfoto-core/src/item_types/key.rs @@ -0,0 +1,3 @@ +use serde::{Deserialize, Serialize}; +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct KeyCore {} diff --git a/crates/idfoto-core/src/item_types/login.rs b/crates/idfoto-core/src/item_types/login.rs new file mode 100644 index 0000000..4ab7756 --- /dev/null +++ b/crates/idfoto-core/src/item_types/login.rs @@ -0,0 +1,3 @@ +use serde::{Deserialize, Serialize}; +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct LoginCore {} diff --git a/crates/idfoto-core/src/item_types/mod.rs b/crates/idfoto-core/src/item_types/mod.rs new file mode 100644 index 0000000..eb6d2d1 --- /dev/null +++ b/crates/idfoto-core/src/item_types/mod.rs @@ -0,0 +1,73 @@ +//! Per-type "core" structs for typed items. +//! +//! Each variant lives in its own submodule. The `ItemCore` enum + match +//! exhaustiveness is the extension mechanism — adding a new variant later +//! means: create the submodule, add the enum variant, fix the match arms +//! the compiler points at, register the popup form (Plan 1C). + +use serde::{Deserialize, Serialize}; + +pub mod login; +pub mod secure_note; +pub mod identity; +pub mod card; +pub mod key; +pub mod document; +pub mod totp; + +pub use login::LoginCore; +pub use secure_note::SecureNoteCore; +pub use identity::IdentityCore; +pub use card::{CardCore, CardKind}; +pub use key::KeyCore; +pub use document::DocumentCore; +pub use totp::{TotpCore, TotpConfig, TotpAlgorithm, TotpKind}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum ItemType { + Login, + SecureNote, + Identity, + Card, + Key, + Document, + Totp, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum ItemCore { + Login(LoginCore), + SecureNote(SecureNoteCore), + Identity(IdentityCore), + Card(CardCore), + Key(KeyCore), + Document(DocumentCore), + Totp(TotpCore), +} + +impl ItemCore { + pub fn item_type(&self) -> ItemType { + match self { + ItemCore::Login(_) => ItemType::Login, + ItemCore::SecureNote(_) => ItemType::SecureNote, + ItemCore::Identity(_) => ItemType::Identity, + ItemCore::Card(_) => ItemType::Card, + ItemCore::Key(_) => ItemType::Key, + ItemCore::Document(_) => ItemType::Document, + ItemCore::Totp(_) => ItemType::Totp, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn item_type_serializes_snake_case() { + let json = serde_json::to_string(&ItemType::SecureNote).unwrap(); + assert_eq!(json, "\"secure_note\""); + } +} diff --git a/crates/idfoto-core/src/item_types/secure_note.rs b/crates/idfoto-core/src/item_types/secure_note.rs new file mode 100644 index 0000000..271c222 --- /dev/null +++ b/crates/idfoto-core/src/item_types/secure_note.rs @@ -0,0 +1,3 @@ +use serde::{Deserialize, Serialize}; +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct SecureNoteCore {} diff --git a/crates/idfoto-core/src/item_types/totp.rs b/crates/idfoto-core/src/item_types/totp.rs new file mode 100644 index 0000000..253398e --- /dev/null +++ b/crates/idfoto-core/src/item_types/totp.rs @@ -0,0 +1,28 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct TotpCore {} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct TotpConfig {} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "snake_case")] +pub enum TotpAlgorithm { + #[default] + Sha1, + Sha256, + Sha512, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum TotpKind { + Totp, + Hotp { counter: u64 }, + Steam, +} + +impl Default for TotpKind { + fn default() -> Self { TotpKind::Totp } +} diff --git a/crates/idfoto-core/src/lib.rs b/crates/idfoto-core/src/lib.rs index a43801d..00637fe 100644 --- a/crates/idfoto-core/src/lib.rs +++ b/crates/idfoto-core/src/lib.rs @@ -41,6 +41,9 @@ pub use ids::{AttachmentId, FieldId, ItemId}; pub mod time; pub use time::{now_unix, MonthYear}; +pub mod item_types; +pub use item_types::{ItemCore, ItemType}; + pub mod crypto; pub use crypto::{decrypt, derive_master_key, encrypt, KdfParams};