mod cast_all {
use read_only::cast;
#[cast]
pub struct FullReadOnly {
pub a: i32,
pub b: i32,
}
impl FullReadOnly {
pub fn new(a: i32, b: i32) -> Self {
Self { a, b }
}
}
}
#[test]
fn cast_all_fields_read_only_accessible() {
let v = cast_all::FullReadOnly::new(10, 20);
assert_eq!(v.a, 10);
assert_eq!(v.b, 20);
}
mod cast_selective {
use read_only::cast;
#[cast]
pub struct SelectiveReadOnly {
#[readonly]
pub id: u64,
pub mutable: i32,
}
impl SelectiveReadOnly {
pub fn new(id: u64, mutable: i32) -> Self {
Self { id, mutable }
}
#[allow(dead_code)]
pub fn mutate(&mut self) {
self.id += 1;
self.mutable += 1;
}
}
}
#[test]
fn cast_selective_readonly_fields() {
let mut v = cast_selective::SelectiveReadOnly::new(42, 0);
assert_eq!(v.id, 42);
assert_eq!(v.mutable, 0);
v.mutable = 1;
assert_eq!(v.mutable, 1);
}
mod cast_string {
use read_only::cast;
#[cast]
pub struct WithString {
#[readonly]
pub name: String,
pub count: usize,
}
impl WithString {
pub fn new(name: &str, count: usize) -> Self {
Self {
name: name.to_string(),
count,
}
}
}
}
#[test]
fn cast_with_heap_allocated_types() {
let v = cast_string::WithString::new("hello", 3);
assert_eq!(v.name, "hello");
assert_eq!(v.count, 3);
}
mod cast_vec {
use read_only::cast;
#[cast]
pub struct WithVec {
pub items: Vec<i32>,
}
impl WithVec {
pub fn new(items: Vec<i32>) -> Self {
Self { items }
}
}
}
#[test]
fn cast_with_vec() {
let v = cast_vec::WithVec::new(vec![1, 2, 3]);
assert_eq!(v.items.len(), 3);
assert_eq!(v.items[1], 2);
}
mod cast_multi_readonly {
use read_only::cast;
#[cast]
pub struct WithMultipleReadonly {
#[readonly]
pub x: i32,
#[readonly]
pub y: String,
pub z: f64,
}
impl WithMultipleReadonly {
pub fn new(x: i32, y: &str, z: f64) -> Self {
Self {
x,
y: y.to_string(),
z,
}
}
}
}
#[test]
fn cast_multiple_readonly_fields() {
let v = cast_multi_readonly::WithMultipleReadonly::new(5, "test", std::f64::consts::PI);
assert_eq!(v.x, 5);
assert_eq!(v.y, "test");
assert!((v.z - std::f64::consts::PI).abs() < 1e-10);
}
mod cast_generics {
use read_only::cast;
#[cast]
pub struct WithGenerics<T> {
pub value: T,
}
impl<T> WithGenerics<T> {
pub fn new(value: T) -> Self {
Self { value }
}
}
}
#[test]
fn cast_with_generics() {
let v = cast_generics::WithGenerics::new("hello");
assert_eq!(v.value, "hello");
}
mod embed_device {
use read_only::embed;
#[embed]
pub struct Device {
#[readonly]
pub handle: u64,
pub mutable: i32,
}
impl Device {
pub fn new(handle: u64, mutable: i32) -> Self {
Self {
read_only: ReadOnlyDevice { handle },
mutable,
}
}
}
}
#[test]
fn embed_readonly_accessible_via_deref() {
let v = embed_device::Device::new(99, 7);
assert_eq!(v.handle, 99);
assert_eq!(v.mutable, 7);
}
#[test]
fn embed_mutable_field_writable() {
let mut v = embed_device::Device::new(99, 7);
v.mutable = 42;
assert_eq!(v.mutable, 42);
}
#[test]
fn embed_deref_target_matches() {
let v = embed_device::Device::new(1, 2);
let ro: &embed_device::ReadOnlyDevice = &v;
assert_eq!(ro.handle, 1);
}
mod embed_generics {
use read_only::embed;
#[embed]
pub struct WithGenerics<T: Copy> {
#[readonly]
pub value: T,
#[allow(dead_code)]
pub extra: i32,
}
impl<T: Copy> WithGenerics<T> {
pub fn new(value: T, extra: i32) -> Self {
Self {
read_only: ReadOnlyWithGenerics { value },
extra,
}
}
}
}
#[test]
fn embed_with_generics() {
let v = embed_generics::WithGenerics::new(42u64, 0);
assert_eq!(v.value, 42u64);
}