Lots more updates
Also begin adding rust building capabilities to be able to write rust binaries for some commands.
This commit is contained in:
parent
624508dd14
commit
dd1cfa79e7
52 changed files with 2509 additions and 150 deletions
162
rust/lib/common/src/bitwarden/entry_serde.rs
Normal file
162
rust/lib/common/src/bitwarden/entry_serde.rs
Normal 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"),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue