// MIT License // // Copyright (c) 2023 Robin Doer // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. #![cfg(feature = "derive")] mod common; use nuts_bytes::{Error, FromBytes, Reader}; use crate::common::{ assert_sample_error, map_eq_mod, map_err_from_bytes, map_err_mod, map_from_bytes, map_mod, }; fn default_u16() -> u16 { 666 } #[test] fn unit_struct() { #[derive(Debug, FromBytes, PartialEq)] struct Sample; let mut reader = Reader::new([].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample); } #[test] fn empty_struct() { #[derive(Debug, FromBytes, PartialEq)] struct Sample {} let mut reader = Reader::new([].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample {}); } #[test] fn empty_tuple_struct() { #[derive(Debug, FromBytes, PartialEq)] struct Sample(); let mut reader = Reader::new([].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample {}); } #[test] fn r#struct() { #[derive(Debug, FromBytes, PartialEq)] struct Sample { f1: u16, f2: u32, #[nuts_bytes(map = map_eq_mod)] f3: u8, #[nuts_bytes(map = map_mod)] f4: u16, #[nuts_bytes(map_from_bytes = map_from_bytes)] f5: u16, #[nuts_bytes(map = map_mod, map_from_bytes = map_from_bytes)] f6: u16, #[nuts_bytes(map_from_bytes = map_from_bytes, map = map_mod)] f7: u16, #[nuts_bytes(skip)] f8: u16, #[nuts_bytes(skip, default = default_u16)] f9: u16, } let mut reader = Reader::new([0, 1, 0, 0, 0, 2, 3, 4, 5, 6, 7].as_slice()); let sample = reader.read::().unwrap(); assert_eq!( sample, Sample { f1: 1, f2: 2, f3: 3, f4: 5, f5: 7, f6: 8, f7: 9, f8: 0, f9: 666 } ); } #[test] fn r#struct_map_err() { #[derive(Debug, FromBytes, PartialEq)] struct Sample { f1: u16, #[nuts_bytes(map = map_err_mod)] f2: u32, } let mut reader = Reader::new([0, 1, 0, 0, 0, 2].as_slice()); let err = reader.read::().unwrap_err(); assert_sample_error!(err); } #[test] fn r#struct_map_from_bytes_err() { #[derive(Debug, FromBytes, PartialEq)] struct Sample { f1: u16, #[nuts_bytes(map_from_bytes = map_err_from_bytes)] f2: u32, } let mut reader = Reader::new([0, 1, 0, 0, 0, 2].as_slice()); let err = reader.read::().unwrap_err(); assert_sample_error!(err); } #[test] fn newtype_struct() { #[derive(Debug, FromBytes, PartialEq)] struct Sample(u16); let mut reader = Reader::new([0, 1].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample(1)); } #[test] fn tuple_struct() { #[derive(Debug, FromBytes, PartialEq)] struct Sample( u16, u32, #[nuts_bytes(map = map_eq_mod)] u8, #[nuts_bytes(map = map_mod)] u16, #[nuts_bytes(map_from_bytes = map_from_bytes)] u16, #[nuts_bytes(map = map_mod, map_from_bytes = map_from_bytes)] u16, #[nuts_bytes(map_from_bytes = map_from_bytes, map = map_mod)] u16, #[nuts_bytes(skip)] u16, #[nuts_bytes(skip, default = default_u16)] u16, ); let mut reader = Reader::new([0, 1, 0, 0, 0, 2, 3, 4, 5, 6, 7].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample(1, 2, 3, 5, 7, 8, 9, 0, 666)); } #[test] fn tuple_struct_map_err() { #[derive(Debug, FromBytes, PartialEq)] struct Sample(u16, #[nuts_bytes(map = map_err_mod)] u32); let mut reader = Reader::new([0, 1, 0, 0, 0, 2].as_slice()); let err = reader.read::().unwrap_err(); assert_sample_error!(err); } #[test] fn tuple_struct_map_from_bytes_err() { #[derive(Debug, FromBytes, PartialEq)] struct Sample(u16, #[nuts_bytes(map_from_bytes = map_err_from_bytes)] u32); let mut reader = Reader::new([0, 1, 0, 0, 0, 2].as_slice()); let err = reader.read::().unwrap_err(); assert_sample_error!(err); } // #[test] // fn zero_variant_enum() { // #[derive(FromBytes)] // enum Sample {} // // // error: zero-variant enums cannot be instantiated // } #[test] fn r#enum() { #[derive(Debug, FromBytes, PartialEq)] enum Sample { V0, V1 {}, V2 { f1: u16 }, V3 { f1: u16, f2: u32 }, V4(), V5(u16), V6(u16, u32), } let mut reader = Reader::new([0, 0, 0, 0].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V0); let mut reader = Reader::new([0, 0, 0, 1].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V1 {}); let mut reader = Reader::new([0, 0, 0, 2, 0, 1].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V2 { f1: 1 }); let mut reader = Reader::new([0, 0, 0, 3, 0, 1, 0, 0, 0, 2].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V3 { f1: 1, f2: 2 }); let mut reader = Reader::new([0, 0, 0, 4].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V4()); let mut reader = Reader::new([0, 0, 0, 5, 0, 1].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V5(1)); let mut reader = Reader::new([0, 0, 0, 6, 0, 1, 0, 0, 0, 2].as_slice()); let sample = reader.read::().unwrap(); assert_eq!(sample, Sample::V6(1, 2)); let mut reader = Reader::new([0, 0, 0, 7].as_slice()); let err = reader.read::().unwrap_err(); assert!(matches!(err, Error::InvalidVariantIndex(7))); }