Lots more updates

Also begin adding rust building capabilities
to be able to write rust binaries for some commands.
This commit is contained in:
Kaare Hoff Skovgaard 2025-07-06 22:37:16 +02:00
parent 624508dd14
commit dd1cfa79e7
Signed by: khs
GPG key ID: C7D890804F01E9F0
52 changed files with 2509 additions and 150 deletions

View file

@ -0,0 +1,162 @@
use serde::{Deserialize, Serialize, ser::SerializeMap};
use crate::bitwarden::{
BitwardenEntryTypeCard, BitwardenEntryTypeData, BitwardenEntryTypeIdentity,
BitwardenEntryTypeLogin, BitwardenEntryTypeSecureNote,
};
impl Serialize for super::BitwardenEntryTypeData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut map = serializer.serialize_map(Some(2))?;
match self {
Self::Login(login) => {
map.serialize_entry("type", &BitwardenEntryType::Login)?;
map.serialize_entry("login", login)?;
}
Self::Card(card) => {
map.serialize_entry("type", &BitwardenEntryType::Card)?;
map.serialize_entry("card", &card)?;
}
Self::SecureNote(secure_note) => {
map.serialize_entry("type", &BitwardenEntryType::SecureNote)?;
map.serialize_entry("secureNote", &secure_note)?;
}
Self::Identity(identity) => {
map.serialize_entry("type", &BitwardenEntryType::Identity)?;
map.serialize_entry("identity", &identity)?;
}
}
map.end()
}
}
impl<'de> Deserialize<'de> for BitwardenEntryTypeData {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_struct(
"BitwardenEntryTypeData",
&["type", "login", "card", "secureNote", "identity"],
DeserializeVisitor,
)
}
}
struct DeserializeVisitor;
impl<'de> serde::de::Visitor<'de> for DeserializeVisitor {
type Value = BitwardenEntryTypeData;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an object with type and tagged type property")
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: serde::de::MapAccess<'de>,
{
let mut entry_type: Option<BitwardenEntryType> = None;
let mut login_data: Option<BitwardenEntryTypeLogin> = None;
let mut secure_note_data: Option<BitwardenEntryTypeSecureNote> = None;
let mut card_data: Option<BitwardenEntryTypeCard> = None;
let mut identity_data: Option<BitwardenEntryTypeIdentity> = None;
while let Some(key) = map.next_key::<&str>()? {
match key {
"type" => {
if entry_type.is_some() {
return Err(serde::de::Error::duplicate_field("type"));
}
entry_type = Some(map.next_value()?);
}
"login" => {
if login_data.is_some() {
return Err(serde::de::Error::duplicate_field("login"));
}
login_data = Some(map.next_value()?);
}
"card" => {
if card_data.is_some() {
return Err(serde::de::Error::duplicate_field("card"));
}
card_data = Some(map.next_value()?);
}
"identity" => {
if identity_data.is_some() {
return Err(serde::de::Error::duplicate_field("identity"));
}
identity_data = Some(map.next_value()?);
}
"secureNote" => {
if secure_note_data.is_some() {
return Err(serde::de::Error::duplicate_field("secureNote"));
}
secure_note_data = Some(map.next_value()?);
}
_ => {}
}
}
match entry_type {
Some(BitwardenEntryType::Login) => {
let login = login_data.ok_or(serde::de::Error::missing_field("login"))?;
Ok(BitwardenEntryTypeData::Login(login))
}
Some(BitwardenEntryType::Card) => {
let card = card_data.ok_or(serde::de::Error::missing_field("card"))?;
Ok(BitwardenEntryTypeData::Card(card))
}
Some(BitwardenEntryType::SecureNote) => {
let secure_note =
secure_note_data.ok_or(serde::de::Error::missing_field("secure_note"))?;
Ok(BitwardenEntryTypeData::SecureNote(secure_note))
}
Some(BitwardenEntryType::Identity) => {
let identity = identity_data.ok_or(serde::de::Error::missing_field("identity"))?;
Ok(BitwardenEntryTypeData::Identity(identity))
}
None => Err(serde::de::Error::missing_field("type")),
}
}
}
#[derive(Debug, serde_repr::Serialize_repr, serde_repr::Deserialize_repr)]
#[repr(u8)]
enum BitwardenEntryType {
Login = 1,
SecureNote = 2,
Card = 3,
Identity = 4,
}
#[cfg(test)]
mod tests {
use crate::json;
use super::*;
#[test]
pub fn test_simple_serializing() {
let d = BitwardenEntryTypeData::Login(BitwardenEntryTypeLogin {
username: None,
password: None,
totp: None,
uris: None,
});
let json = json::to_string(&d).unwrap();
assert_eq!(
json,
r#"{"type":1,"login":{"username":null,"password":null,"totp":null,"uris":null}}"#
);
match json::from_str(&json).unwrap() {
BitwardenEntryTypeData::Login(BitwardenEntryTypeLogin {
username: None,
password: None,
totp: None,
uris: None,
}) => {}
_ => panic!("Could not deserialize json to itself"),
}
}
}