use serde::{Deserialize, Serialize};
use crate::{B64Url, EditableField, EditableFieldString, EditableFieldValue, Extension};
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", bound(deserialize = "E: Deserialize<'de>"))]
pub struct CustomFieldsCredential<E = ()> {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<B64Url>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
pub fields: Vec<EditableFieldValue<E>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub extensions: Vec<Extension<E>>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FileCredential {
pub id: B64Url,
pub name: String,
pub decrypted_size: u64,
pub integrity_hash: B64Url,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", bound(deserialize = "E: Deserialize<'de>"))]
pub struct NoteCredential<E = ()> {
pub content: EditableField<EditableFieldString, E>,
}
#[cfg(test)]
mod tests {
use chrono::Month;
use serde_json::json;
use super::*;
use crate::{EditableFieldBoolean, EditableFieldString, EditableFieldYearMonth};
#[test]
fn test_serialize_custom_fields() {
let credential = CustomFieldsCredential {
id: None,
label: None,
fields: vec![
EditableFieldValue::<()>::String(EditableField {
id: Some(B64Url::from(b"field1".as_slice())),
value: EditableFieldString("hello".into()),
label: None,
extensions: None,
}),
EditableFieldValue::<()>::Boolean(EditableField {
id: None,
value: EditableFieldBoolean(false),
label: None,
extensions: None,
}),
],
extensions: vec![],
};
let json = json!({
"fields": [
{
"id": "ZmllbGQx",
"fieldType": "string",
"value": "hello"
},
{
"fieldType": "boolean",
"value": "false"
}
]
});
assert_eq!(serde_json::to_value(&credential).unwrap(), json);
}
#[test]
fn test_deserialize_custom_fields() {
let json = json!({
"fields": [
{
"fieldType": "string",
"value": "hello"
},
{
"fieldType": "concealed-string",
"value": "world"
},
{
"fieldType": "boolean",
"value": "false"
},
{
"fieldType": "year-month",
"value": "2025-02"
}
]
});
let json = serde_json::to_string(&json).unwrap();
let credential: CustomFieldsCredential = serde_json::from_str(&json).unwrap();
assert_eq!(credential.id, None);
assert_eq!(credential.label, None);
assert_eq!(credential.extensions.len(), 0);
assert_eq!(credential.fields.len(), 4);
match &credential.fields[0] {
EditableFieldValue::String(field) => {
assert_eq!(field.value.0, "hello");
}
_ => panic!("Expected string field"),
}
match &credential.fields[1] {
EditableFieldValue::ConcealedString(field) => {
assert_eq!(field.value.0, "world");
}
_ => panic!("Expected concealed string field"),
}
match &credential.fields[2] {
EditableFieldValue::Boolean(field) => {
assert!(!field.value.0);
}
_ => panic!("Expected boolean field"),
}
match &credential.fields[3] {
EditableFieldValue::YearMonth(field) => {
assert_eq!(
field.value,
EditableFieldYearMonth {
year: 2025,
month: Month::February,
}
);
}
_ => panic!("Expected boolean field"),
}
}
}