use serde::{Deserialize, Serialize};
use crate::{
AndaDBSchema, ByteArrayB64, ByteBufB64, FieldEntry, FieldKey, FieldType, FieldTyped, Json, Map,
Schema, SchemaError,
};
#[derive(Debug, Default, Clone, Serialize, Deserialize, FieldTyped, PartialEq, AndaDBSchema)]
pub struct Resource {
pub _id: u64,
pub tags: Vec<String>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mime_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub blob: Option<ByteBufB64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
#[unique]
pub hash: Option<ByteArrayB64<32>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Map<String, Json>>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Document, FieldValue};
use std::sync::Arc;
#[test]
fn resource_schema_marks_hash_unique() {
let schema = Resource::schema().unwrap();
let id = schema.get_field("_id").unwrap();
assert_eq!(id.r#type(), &FieldType::U64);
assert!(id.unique());
let hash = schema.get_field("hash").unwrap();
assert!(hash.unique());
assert_eq!(
hash.r#type(),
&FieldType::Option(Box::new(FieldType::Bytes))
);
assert!(!hash.required());
let name = schema.get_field("name").unwrap();
assert_eq!(name.r#type(), &FieldType::Text);
assert!(name.required());
assert!(!name.unique());
}
#[test]
fn resource_with_blob_and_hash_roundtrips_through_document() {
let schema = Arc::new(Resource::schema().unwrap());
let resource = Resource {
_id: 7,
tags: vec!["image".to_string(), "png".to_string()],
name: "avatar.png".to_string(),
description: Some("profile picture".to_string()),
uri: None,
mime_type: Some("image/png".to_string()),
blob: Some(vec![0x89, 0x50, 0x4E, 0x47].into()),
size: Some(4),
hash: Some([7u8; 32].into()),
metadata: None,
};
let doc = Document::try_from(schema.clone(), &resource).unwrap();
assert_eq!(
doc.get_field("blob").unwrap(),
&FieldValue::Bytes(vec![0x89, 0x50, 0x4E, 0x47])
);
assert_eq!(
doc.get_field("hash").unwrap(),
&FieldValue::Bytes(vec![7u8; 32])
);
let decoded: Resource = doc.try_into().unwrap();
assert_eq!(decoded, resource);
}
}