use crate::session::SessionManifest;
use crate::{Error, Mode, Result, FONT_VERSION, PROTOCOL_VERSION};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct DocumentFlags(u8);
impl DocumentFlags {
pub const NONE: Self = Self(0);
pub const COMPRESSED: Self = Self(0b0000_0001);
pub const ECC: Self = Self(0b0000_0010);
pub const fn from_bits(bits: u8) -> Self {
Self(bits)
}
pub const fn bits(self) -> u8 {
self.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DocumentHeader {
pub version: u8,
pub mode: Mode,
#[serde(default)]
pub flags: DocumentFlags,
#[serde(default)]
pub checksum: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub mapping_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub session: Option<SessionManifest>,
#[serde(skip_serializing_if = "Option::is_none")]
pub char_count: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub byte_count: Option<u64>,
#[serde(default = "default_font_version")]
pub font_version: u32,
#[serde(default, skip_serializing_if = "serde_json::Map::is_empty")]
pub meta: serde_json::Map<String, serde_json::Value>,
}
fn default_font_version() -> u32 {
FONT_VERSION
}
impl DocumentHeader {
pub fn new(mode: Mode) -> Self {
Self {
version: PROTOCOL_VERSION,
mode,
flags: DocumentFlags::NONE,
checksum: 0,
mapping_id: None,
session: None,
char_count: None,
byte_count: None,
font_version: FONT_VERSION,
meta: serde_json::Map::new(),
}
}
pub fn to_bytes(&self) -> Result<Vec<u8>> {
let mut for_ser = self.clone();
for_ser.checksum = 0;
serde_json::to_vec(&for_ser).map_err(|e| Error::InvalidManifest(e.to_string()))
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
serde_json::from_slice(bytes).map_err(|e| Error::InvalidManifest(e.to_string()))
}
}
impl Serialize for DocumentFlags {
fn serialize<S: serde::Serializer>(
&self,
serializer: S,
) -> std::result::Result<S::Ok, S::Error> {
serializer.serialize_u8(self.bits())
}
}
impl<'de> Deserialize<'de> for DocumentFlags {
fn deserialize<D: serde::Deserializer<'de>>(
deserializer: D,
) -> std::result::Result<Self, D::Error> {
let bits = u8::deserialize(deserializer)?;
Ok(DocumentFlags::from_bits(bits))
}
}