diff options
-rw-r--r-- | shared/src/resources.rs | 490 |
1 files changed, 142 insertions, 348 deletions
diff --git a/shared/src/resources.rs b/shared/src/resources.rs index 19ce6b2..f9a22bf 100644 --- a/shared/src/resources.rs +++ b/shared/src/resources.rs @@ -24,104 +24,147 @@ use std::{ io::{Read, Write}, }; -#[derive(Debug, Default, Clone)] -pub struct Prefab { - pub name: Option<String>, - pub mesh: Vec<(Affine3A, Resource<MeshPart>)>, - pub collision: Vec<(Affine3A, Resource<CollisionPart>)>, - pub light: Vec<(Vec3A, Resource<LightPart>)>, - pub armature: Vec<Resource<ArmaturePart>>, - pub particles: Vec<(Affine3A, Resource<ParticlesPart>)>, - pub environment: Option<Resource<EnvironmentPart>>, +macro_rules! rd_member_type { + (multi, $t:ty) => { Vec<$t> }; + (, $t:ty) => { Option<$t> }; } - -#[derive(Debug, Default, Clone)] -pub struct LightPart { - pub name: Option<String>, - pub emission: Option<Vec3A>, - pub radius: Option<f32>, +macro_rules! rd_member_read { + (multi, $n:ident, $s:ident, $v:ident) => { + Ok($s.$n.push(read_slice($v)?)) + }; + (, $n:ident, $s:ident, $v:ident) => { + Ok($s.$n = Some(read_slice($v)?)) + }; } - -#[derive(Debug, Default, Clone)] -pub struct EnvironmentPart { - pub skybox: Option<Resource<Image<'static>>>, - pub sun: Option<(Vec3A, Vec3A)>, +macro_rules! rd_member_write { + (multi, $n:ident, $s:ident, $w:ident) => { + for x in &$s.$n { + write_kv_opt($w, stringify!($n), &Some(x.clone()))?; + } + }; + (, $n:ident, $s:ident, $w:ident) => { + write_kv_opt($w, stringify!($n), &$s.$n)? + }; } - -#[derive(Debug, Default, Clone)] -pub struct ParticlesPart { - pub sprite: Option<Resource<MeshPart>>, - pub density: Option<f32>, - pub lifetime: Option<f32>, - pub lifetime_spread: Option<f32>, - pub velocity: Option<Vec3A>, - pub velocity_spread: Option<Vec3A>, +macro_rules! resource_dict { + ($svis:vis struct $sname:ident { $($mname:ident$([$mflags:ident])?: $mty:ty),*, }) => { + #[derive(Debug, Default, Clone)] + $svis struct $sname { $(pub $mname: rd_member_type!($($mflags)?, $mty)),*, } + impl ReadWrite for $sname { + fn write(&self, w: &mut dyn Write) -> Result<()> { + $(rd_member_write!($($mflags)?, $mname, self, w);)* + Ok(()) + } + fn read(r: &mut dyn Read) -> Result<Self> { + let mut s = Self::default(); + read_kv_iter(r, |k, v| match k { + $(stringify!($mname) => rd_member_read!($($mflags)?, $mname, s, v)),*, + x => Ok(warn!("unknown {} key: {x:?}", stringify!($sname))), + })?; + Ok(s) + } + } + }; } - -#[derive(Debug, Default, Clone)] -pub struct MeshPart { - pub name: Option<String>, - pub index: Option<Resource<Vec<[u32; 3]>>>, - pub armature: Option<u32>, - pub g_metallic: Option<f32>, - pub g_roughness: Option<f32>, - pub g_albedo: Option<Vec3A>, - pub g_transmission: Option<f32>, - pub g_alpha: Option<f32>, - pub g_emission: Option<Vec3A>, - pub g_thickness: Option<f32>, - pub g_refractive_index: Option<f32>, - pub g_attenuation: Option<Vec3A>, - pub g_dispersion: Option<f32>, - pub g_unlit: Option<()>, - pub g_double_sided: Option<()>, - pub va_position: Option<Resource<Vec<Vec3A>>>, - pub va_normal: Option<Resource<Vec<Vec3A>>>, - pub va_tangent: Option<Resource<Vec<Vec4>>>, - pub va_texcoord: Option<Resource<Vec<Vec2>>>, - pub va_roughness: Option<Resource<Vec<f32>>>, - pub va_metallic: Option<Resource<Vec<f32>>>, - pub va_albedo: Option<Resource<Vec<Vec3A>>>, - pub va_transmission: Option<Resource<Vec<f32>>>, - pub va_alpha: Option<Resource<Vec<f32>>>, - pub va_emission: Option<Resource<Vec<Vec3A>>>, - pub va_joint_index: Option<Resource<Vec<[u32; 4]>>>, - pub va_joint_weight: Option<Resource<Vec<[f32; 4]>>>, - pub tex_normal: Option<Resource<Image<'static>>>, - pub tex_roughness: Option<Resource<Image<'static>>>, - pub tex_metallic: Option<Resource<Image<'static>>>, - pub tex_albedo: Option<Resource<Image<'static>>>, - pub tex_transmission: Option<Resource<Image<'static>>>, - pub tex_alpha: Option<Resource<Image<'static>>>, - pub tex_emission: Option<Resource<Image<'static>>>, - pub tex_thickness: Option<Resource<Image<'static>>>, - pub tex_occlusion: Option<Resource<Image<'static>>>, - pub hint_mirror: Option<()>, - pub hint_hide_first_person: Option<()>, - pub hint_static: Option<()>, - pub hint_volume: Option<()>, +macro_rules! resource_dicts { + ($(pub struct $name:ident $c:tt)*) => { + $(resource_dict!(pub struct $name $c);)* + }; } -#[derive(Debug, Default, Clone)] -pub struct ArmaturePart { - pub parent: Option<Vec<u16>>, - pub transform: Option<Vec<Affine3A>>, - pub name: Option<Vec<String>>, -} +resource_dicts!( + pub struct Prefab { + name: String, + mesh[multi]: (Affine3A, Resource<MeshPart>), + collision[multi]: (Affine3A, Resource<CollisionPart>), + light[multi]: (Vec3A, Resource<LightPart>), + armature[multi]: Resource<ArmaturePart>, + particles[multi]: (Affine3A, Resource<ParticlesPart>), + environment: Resource<EnvironmentPart>, + } -#[derive(Debug, Default, Clone)] -pub struct CollisionPart { - pub name: Option<String>, - pub restitution_coeff: Option<f32>, - pub friction_kinetic: Option<f32>, - pub friction_static: Option<f32>, - pub sh_box: Option<Vec3A>, - pub sh_sphere: Option<f32>, - pub sh_cylinder: Option<(f32, f32, f32)>, - pub sh_capsule: Option<(f32, f32, f32)>, - pub sh_convex_hull: Option<Resource<Vec<Vec3A>>>, - pub sh_mesh: Option<(Resource<Vec<[u32; 3]>>, Resource<Vec<Vec3A>>)>, -} + pub struct LightPart { + name: String, + emission: Vec3A, + radius: f32, + } + + pub struct EnvironmentPart { + skybox: Resource<Image<'static>>, + sun: (Vec3A, Vec3A), + } + + pub struct ParticlesPart { + sprite: Resource<MeshPart>, + density: f32, + lifetime: f32, + lifetime_spread: f32, + velocity: Vec3A, + velocity_spread: Vec3A, + } + + pub struct MeshPart { + name: String, + index: Resource<Vec<[u32; 3]>>, + armature: u32, + g_metallic: f32, + g_roughness: f32, + g_albedo: Vec3A, + g_transmission: f32, + g_alpha: f32, + g_emission: Vec3A, + g_thickness: f32, + g_refractive_index: f32, + g_attenuation: Vec3A, + g_dispersion: f32, + g_unlit: (), + g_double_sided: (), + va_position: Resource<Vec<Vec3A>>, + va_normal: Resource<Vec<Vec3A>>, + va_tangent: Resource<Vec<Vec4>>, + va_texcoord: Resource<Vec<Vec2>>, + va_roughness: Resource<Vec<f32>>, + va_metallic: Resource<Vec<f32>>, + va_albedo: Resource<Vec<Vec3A>>, + va_transmission: Resource<Vec<f32>>, + va_alpha: Resource<Vec<f32>>, + va_emission: Resource<Vec<Vec3A>>, + va_joint_index: Resource<Vec<[u32; 4]>>, + va_joint_weight: Resource<Vec<[f32; 4]>>, + tex_normal: Resource<Image<'static>>, + tex_roughness: Resource<Image<'static>>, + tex_metallic: Resource<Image<'static>>, + tex_albedo: Resource<Image<'static>>, + tex_transmission: Resource<Image<'static>>, + tex_alpha: Resource<Image<'static>>, + tex_emission: Resource<Image<'static>>, + tex_thickness: Resource<Image<'static>>, + tex_occlusion: Resource<Image<'static>>, + hint_mirror: (), + hint_hide_first_person: (), + hint_static: (), + hint_volume: (), + } + + pub struct ArmaturePart { + parent: Vec<u16>, + transform: Vec<Affine3A>, + name: Vec<String>, + } + + pub struct CollisionPart { + name: String, + restitution_coeff: f32, + friction_kinetic: f32, + friction_static: f32, + sh_box: Vec3A, + sh_sphere: f32, + sh_cylinder: (f32, f32, f32), + sh_capsule: (f32, f32, f32), + sh_convex_hull: Resource<Vec<Vec3A>>, + sh_mesh: (Resource<Vec<[u32; 3]>>, Resource<Vec<Vec3A>>), + } +); #[derive(Debug, Default, Clone)] pub struct PrefabIndex(pub BTreeMap<String, Resource<Prefab>>); @@ -132,7 +175,7 @@ pub struct Image<'a>(pub Cow<'a, [u8]>); impl ReadWrite for PrefabIndex { fn write(&self, w: &mut dyn Write) -> Result<()> { for (k, v) in &self.0 { - write_kv(w, k.as_bytes(), &v.0)?; + write_kv(w, k, &v.0)?; } Ok(()) } @@ -143,262 +186,13 @@ impl ReadWrite for PrefabIndex { let mut g = g.as_slice(); while !g.is_empty() { let (k, v) = read_kv(&mut g)?; - s.0.insert(String::from_utf8(k)?, Resource::read(&mut v.as_slice())?); + s.0.insert(k, Resource::read(&mut v.as_slice())?); } Ok(s) } } -impl ReadWrite for ArmaturePart { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"parent", &self.parent)?; - write_kv_opt(w, b"transform", &self.transform)?; - write_kv_opt(w, b"name", &self.name)?; - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"parent" => Ok(s.parent = Some(read_slice(v)?)), - b"name" => Ok(s.name = Some(read_slice(v)?)), - b"transform" => Ok(s.transform = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown armature key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} -impl ReadWrite for CollisionPart { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"name", &self.name)?; - write_kv_opt(w, b"restitution_coeff", &self.restitution_coeff)?; - write_kv_opt(w, b"friction_kinetic", &self.friction_kinetic)?; - write_kv_opt(w, b"friction_static", &self.friction_static)?; - write_kv_opt(w, b"sh_box", &self.sh_box)?; - write_kv_opt(w, b"sh_sphere", &self.sh_sphere)?; - write_kv_opt(w, b"sh_cylinder", &self.sh_cylinder)?; - write_kv_opt(w, b"sh_capsule", &self.sh_capsule)?; - write_kv_opt(w, b"sh_convex_hull", &self.sh_convex_hull)?; - write_kv_opt(w, b"sh_mesh", &self.sh_mesh)?; - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"name" => Ok(s.name = Some(read_slice(v)?)), - b"restitution_coeff" => Ok(s.restitution_coeff = Some(read_slice(v)?)), - b"friction_kinetic" => Ok(s.friction_kinetic = Some(read_slice(v)?)), - b"friction_static" => Ok(s.friction_static = Some(read_slice(v)?)), - b"sh_box" => Ok(s.sh_box = Some(read_slice(v)?)), - b"sh_sphere" => Ok(s.sh_sphere = Some(read_slice(v)?)), - b"sh_cylinder" => Ok(s.sh_cylinder = Some(read_slice(v)?)), - b"sh_capsule" => Ok(s.sh_capsule = Some(read_slice(v)?)), - b"sh_convex_hull" => Ok(s.sh_convex_hull = Some(read_slice(v)?)), - b"sh_mesh" => Ok(s.sh_mesh = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown prefab key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} -impl ReadWrite for Prefab { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"name", &self.name)?; - for x in &self.mesh { - write_kv_opt(w, b"mesh", &Some(x.clone()))?; - } - for x in &self.collision { - write_kv_opt(w, b"collision", &Some(x.clone()))?; - } - for x in &self.light { - write_kv_opt(w, b"light", &Some(x.clone()))?; - } - for x in &self.armature { - write_kv_opt(w, b"armature", &Some(x.clone()))?; - } - for x in &self.particles { - write_kv_opt(w, b"particles", &Some(x.clone()))?; - } - write_kv_opt(w, b"environment", &self.environment)?; - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"name" => Ok(s.name = Some(read_slice(v)?)), - b"mesh" => Ok(s.mesh.push(read_slice(v)?)), - b"collision" => Ok(s.collision.push(read_slice(v)?)), - b"light" => Ok(s.light.push(read_slice(v)?)), - b"armature" => Ok(s.armature.push(read_slice(v)?)), - b"particles" => Ok(s.particles.push(read_slice(v)?)), - b"environment" => Ok(s.environment = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown prefab key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} -impl ReadWrite for LightPart { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"name", &self.name)?; - write_kv_opt(w, b"emission", &self.emission)?; - write_kv_opt(w, b"radius", &self.radius)?; - Ok(()) - } - - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"name" => Ok(s.name = Some(read_slice(v)?)), - b"emission" => Ok(s.emission = Some(read_slice(v)?)), - b"radius" => Ok(s.radius = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown light part key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} -impl ReadWrite for EnvironmentPart { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"skybox", &self.skybox)?; - write_kv_opt(w, b"sun", &self.sun)?; - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"skybox" => Ok(s.skybox = Some(read_slice(v)?)), - b"sun" => Ok(s.sun = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown environment part key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} -impl ReadWrite for ParticlesPart { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"density", &self.density)?; - write_kv_opt(w, b"sprite", &self.sprite)?; - write_kv_opt(w, b"lifetime", &self.lifetime)?; - write_kv_opt(w, b"lifetime_spread", &self.lifetime_spread)?; - write_kv_opt(w, b"velocity", &self.velocity)?; - write_kv_opt(w, b"velocity_spread", &self.velocity_spread)?; - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"density" => Ok(s.density = Some(read_slice(v)?)), - b"sprite" => Ok(s.sprite = Some(read_slice(v)?)), - b"lifetime" => Ok(s.lifetime = Some(read_slice(v)?)), - b"lifetime_spread" => Ok(s.lifetime_spread = Some(read_slice(v)?)), - b"velocity" => Ok(s.velocity = Some(read_slice(v)?)), - b"velocity_spread" => Ok(s.velocity_spread = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown environment part key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} -impl ReadWrite for MeshPart { - fn write(&self, w: &mut dyn Write) -> Result<()> { - write_kv_opt(w, b"name", &self.name)?; - write_kv_opt(w, b"index", &self.index)?; - write_kv_opt(w, b"armature", &self.armature)?; - write_kv_opt(w, b"g_metallic", &self.g_metallic)?; - write_kv_opt(w, b"g_roughness", &self.g_roughness)?; - write_kv_opt(w, b"g_albedo", &self.g_albedo)?; - write_kv_opt(w, b"g_transmission", &self.g_transmission)?; - write_kv_opt(w, b"g_alpha", &self.g_alpha)?; - write_kv_opt(w, b"g_emission", &self.g_emission)?; - write_kv_opt(w, b"g_unlit", &self.g_unlit)?; - write_kv_opt(w, b"g_double_sided", &self.g_double_sided)?; - write_kv_opt(w, b"va_position", &self.va_position)?; - write_kv_opt(w, b"va_normal", &self.va_normal)?; - write_kv_opt(w, b"va_tangent", &self.va_tangent)?; - write_kv_opt(w, b"va_texcoord", &self.va_texcoord)?; - write_kv_opt(w, b"va_roughness", &self.va_roughness)?; - write_kv_opt(w, b"va_metallic", &self.va_metallic)?; - write_kv_opt(w, b"va_albedo", &self.va_albedo)?; - write_kv_opt(w, b"va_transmission", &self.va_transmission)?; - write_kv_opt(w, b"va_alpha", &self.va_transmission)?; - write_kv_opt(w, b"va_emission", &self.va_emission)?; - write_kv_opt(w, b"va_joint_weight", &self.va_joint_weight)?; - write_kv_opt(w, b"va_joint_index", &self.va_joint_index)?; - write_kv_opt(w, b"tex_normal", &self.tex_normal)?; - write_kv_opt(w, b"tex_roughness", &self.tex_roughness)?; - write_kv_opt(w, b"tex_metallic", &self.tex_metallic)?; - write_kv_opt(w, b"tex_albedo", &self.tex_albedo)?; - write_kv_opt(w, b"tex_transmission", &self.tex_transmission)?; - write_kv_opt(w, b"tex_alpha", &self.tex_alpha)?; - write_kv_opt(w, b"tex_emission", &self.tex_emission)?; - write_kv_opt(w, b"tex_occlusion", &self.tex_occlusion)?; - write_kv_opt(w, b"hint_mirror", &self.hint_mirror)?; - write_kv_opt(w, b"hint_hide_first_person", &self.hint_hide_first_person)?; - write_kv_opt(w, b"hint_static", &self.hint_static)?; - write_kv_opt(w, b"hint_volume", &self.hint_volume)?; - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - let mut s = Self::default(); - read_kv_iter(r, |k, v| match k { - b"name" => Ok(s.name = Some(read_slice(v)?)), - b"index" => Ok(s.index = Some(read_slice(v)?)), - b"armature" => Ok(s.armature = Some(read_slice(v)?)), - b"g_metallic" => Ok(s.g_metallic = Some(read_slice(v)?)), - b"g_roughness" => Ok(s.g_roughness = Some(read_slice(v)?)), - b"g_albedo" => Ok(s.g_albedo = Some(read_slice(v)?)), - b"g_transmission" => Ok(s.g_transmission = Some(read_slice(v)?)), - b"g_alpha" => Ok(s.g_alpha = Some(read_slice(v)?)), - b"g_emission" => Ok(s.g_emission = Some(read_slice(v)?)), - b"g_unlit" => Ok(s.g_unlit = Some(read_slice(v)?)), - b"g_double_sided" => Ok(s.g_double_sided = Some(read_slice(v)?)), - b"va_position" => Ok(s.va_position = Some(read_slice(v)?)), - b"va_normal" => Ok(s.va_normal = Some(read_slice(v)?)), - b"va_tangent" => Ok(s.va_tangent = Some(read_slice(v)?)), - b"va_texcoord" => Ok(s.va_texcoord = Some(read_slice(v)?)), - b"va_roughness" => Ok(s.va_roughness = Some(read_slice(v)?)), - b"va_metallic" => Ok(s.va_metallic = Some(read_slice(v)?)), - b"va_albedo" => Ok(s.va_albedo = Some(read_slice(v)?)), - b"va_transmission" => Ok(s.va_transmission = Some(read_slice(v)?)), - b"va_alpha" => Ok(s.va_alpha = Some(read_slice(v)?)), - b"va_emission" => Ok(s.va_emission = Some(read_slice(v)?)), - b"va_joint_weight" => Ok(s.va_joint_weight = Some(read_slice(v)?)), - b"va_joint_index" => Ok(s.va_joint_index = Some(read_slice(v)?)), - b"tex_normal" => Ok(s.tex_normal = Some(read_slice(v)?)), - b"tex_roughness" => Ok(s.tex_roughness = Some(read_slice(v)?)), - b"tex_metallic" => Ok(s.tex_metallic = Some(read_slice(v)?)), - b"tex_albedo" => Ok(s.tex_albedo = Some(read_slice(v)?)), - b"tex_transmission" => Ok(s.tex_transmission = Some(read_slice(v)?)), - b"tex_alpha" => Ok(s.tex_alpha = Some(read_slice(v)?)), - b"tex_emission" => Ok(s.tex_emission = Some(read_slice(v)?)), - b"tex_occlusion" => Ok(s.tex_occlusion = Some(read_slice(v)?)), - b"hint_mirror" => Ok(s.hint_mirror = Some(read_slice(v)?)), - b"hint_hide_first_person" => Ok(s.hint_hide_first_person = Some(read_slice(v)?)), - b"hint_static" => Ok(s.hint_static = Some(read_slice(v)?)), - b"hint_volume" => Ok(s.hint_volume = Some(read_slice(v)?)), - x => Ok(warn!( - "unknown mesh part key: {:?}", - String::from_utf8_lossy(x) - )), - })?; - Ok(s) - } -} - -fn read_kv(r: &mut &[u8]) -> Result<(Vec<u8>, Vec<u8>)> { +fn read_kv(r: &mut &[u8]) -> Result<(String, Vec<u8>)> { let mut key_size = [0; { size_of::<u16>() }]; let mut value_size = [0; { size_of::<u16>() }]; r.read_exact(&mut key_size)?; @@ -409,10 +203,10 @@ fn read_kv(r: &mut &[u8]) -> Result<(Vec<u8>, Vec<u8>)> { let mut value = vec![0; value_size as usize]; r.read_exact(&mut key)?; r.read_exact(&mut value)?; - Ok((key, value)) + Ok((String::from_utf8_lossy_owned(key), value)) } -fn read_kv_iter(r: &mut dyn Read, mut cb: impl FnMut(&[u8], &[u8]) -> Result<()>) -> Result<()> { +fn read_kv_iter(r: &mut dyn Read, mut cb: impl FnMut(&str, &[u8]) -> Result<()>) -> Result<()> { let mut g = Vec::new(); r.read_to_end(&mut g)?; let mut g = g.as_slice(); @@ -426,16 +220,16 @@ fn read_slice<T: ReadWrite>(mut r: &[u8]) -> Result<T> { T::read(&mut r) } -fn write_kv_opt(w: &mut dyn Write, key: &[u8], value: &Option<impl ReadWrite>) -> Result<()> { +fn write_kv_opt(w: &mut dyn Write, key: &str, value: &Option<impl ReadWrite>) -> Result<()> { if let Some(v) = value { write_kv(w, key, &v.write_alloc())?; } Ok(()) } -fn write_kv(w: &mut dyn Write, key: &[u8], value: &[u8]) -> Result<()> { +fn write_kv(w: &mut dyn Write, key: &str, value: &[u8]) -> Result<()> { w.write_all(&(key.len() as u16).to_le_bytes())?; w.write_all(&(value.len() as u16).to_le_bytes())?; - w.write_all(key)?; + w.write_all(key.as_bytes())?; w.write_all(value)?; Ok(()) } |