This repository has been archived on 2026-08-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
donglora/vendor/ssmarshal/tests/roundtrip.rs
T
swaitsandClaude Opus 4.6 3102fc747a feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:42:54 -06:00

240 lines
5.6 KiB
Rust

// Copyright (c) 2017 The Robigalia Project Developers Licensed under the Apache License, Version
// 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. All files in the project
// carrying such notice may not be copied, modified, or distributed except according to those
// terms.
#![feature(proc_macro, plugin)]
#![plugin(quickcheck_macros)]
#![allow(non_snake_case)]
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate quickcheck;
extern crate ssmarshal;
use serde::{Serialize};
use serde::de::DeserializeOwned;
use ssmarshal::{serialize, deserialize};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct U8(u8);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct U16(u16);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct U32(u32);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct U64(u64);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct USize(usize);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct I8(i8);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct I16(i16);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct I32(i32);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct I64(i64);
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct ISize(isize);
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
struct F32(f32);
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
struct F64(f64);
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
struct Simple {
a: u8,
b: u16,
c: u32,
d: u64,
e: i8,
f: f32,
g: u8,
h: f64,
}
impl quickcheck::Arbitrary for Simple {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Simple {
Simple {
a: g.gen(),
b: g.gen(),
c: g.gen(),
d: g.gen(),
e: g.gen(),
f: g.gen(),
g: g.gen(),
h: g.gen(),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
struct Unit;
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
struct Complex {
a: Simple,
e: Unit,
b: Simple,
c: [u8; 7],
d: (),
f: [Unit; 3],
}
impl quickcheck::Arbitrary for Complex {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Complex {
Complex {
a: Simple::arbitrary(g),
b: Simple::arbitrary(g),
c: g.gen(),
d: (),
e: Unit,
f: [Unit; 3],
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
#[repr(C)]
enum ComplexEnum {
A,
B(Simple),
C(u8, u16),
D(isize),
E {
foo: Simple
},
F {
bar: Complex,
baz: Simple,
qux: char
}
}
impl quickcheck::Arbitrary for ComplexEnum {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> ComplexEnum {
match g.gen_range(0, 6) {
0 => {
ComplexEnum::A
},
1 => {
ComplexEnum::B(Simple::arbitrary(g))
},
2 => {
ComplexEnum::C(g.gen(), g.gen())
},
3 => {
ComplexEnum::D(g.gen())
},
4 => {
ComplexEnum::E { foo: Simple::arbitrary(g) }
},
5 => {
ComplexEnum::F { bar: Complex::arbitrary(g), baz: Simple::arbitrary(g), qux: g.gen() }
},
_ => unreachable!()
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
struct TupleStruct(u8, u64, Simple, Option<ComplexEnum>);
impl quickcheck::Arbitrary for TupleStruct {
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> TupleStruct {
TupleStruct(g.gen(), g.gen(), quickcheck::Arbitrary::arbitrary(g), quickcheck::Arbitrary::arbitrary(g))
}
}
fn rt_val<T: Serialize + DeserializeOwned + PartialEq+std::fmt::Debug>(val: &T) -> bool {
let mut buf = vec![0; std::mem::size_of::<T>()];
serialize(&mut buf, val).unwrap();
let new_val: T = deserialize(&buf).unwrap().0;
println!("\n\nOld: {:?}\nNew: {:?}", val, new_val);
val == &new_val
}
#[quickcheck]
fn rt_simple(val: Simple) -> bool {
rt_val(&val)
}
#[quickcheck]
fn rt_complex(val: Complex) -> bool {
rt_val(&val)
}
#[quickcheck]
fn rt_complexenum(val: ComplexEnum) -> bool {
rt_val(&val)
}
#[quickcheck]
fn rt_tuplestruct(val: TupleStruct) -> bool {
rt_val(&val)
}
macro_rules! rt {
($(($name:ident, $t:ty)),*) => {
$(#[quickcheck] fn $name(val: $t) -> bool {
rt_val::<$t>(&val)
})*
}
}
macro_rules! rt_wrap {
($(($name:ident, $t:ty, $n:ident)),*) => {
$(#[quickcheck] fn $name(val: $t) -> bool {
rt_val::<$n>(&$n(val))
})*
}
}
rt! {
(rt_i8, i8),
(rt_i16, i16),
(rt_i32, i32),
(rt_i64, i64),
(rt_u8, u8),
(rt_u16, u16),
(rt_u32, u32),
(rt_u64, u64),
(rt_usize, usize),
(rt_isize, isize),
(rt_f32, f32),
(rt_f64, f64),
(rt_tp1, (u8, u8, u8)),
(rt_tp2, (u8, i16, u8)),
(rt_tp3, (u8, i16, u8)),
(rt_tp4, (usize, i16, isize)),
(rt_char, char)
}
rt_wrap! {
(rt_I8, i8 , I8),
(rt_I16, i16, I16),
(rt_I32, i32, I32),
(rt_I64, i64, I64),
(rt_U8, u8 , U8),
(rt_U16, u16, U16),
(rt_U32, u32, U32),
(rt_U64, u64, U64),
(rt_F32, f32, F32),
(rt_F64, f64, F64)
}