round_trip.rs (4658B)
1 // Copyright 2019 The Servo Project Developers. See the COPYRIGHT 2 // file at the top-level directory of this distribution and at 3 // http://rust-lang.org/COPYRIGHT. 4 // 5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 8 // option. This file may not be copied, modified, or distributed 9 // except according to those terms. 10 11 use peek_poke::{Peek, PeekPoke, Poke}; 12 use std::{fmt::Debug, marker::PhantomData}; 13 14 fn poke_into<V: Peek + Poke>(a: &V) -> Vec<u8> { 15 let mut v = <Vec<u8>>::with_capacity(<V>::max_size()); 16 let end_ptr = unsafe { a.poke_into(v.as_mut_ptr()) }; 17 let new_size = end_ptr as usize - v.as_ptr() as usize; 18 assert!(new_size <= v.capacity()); 19 unsafe { 20 v.set_len(new_size); 21 } 22 v 23 } 24 25 fn the_same<V>(a: V) 26 where 27 V: Debug + Default + PartialEq + Peek + Poke, 28 { 29 let v = poke_into(&a); 30 let (b, end_ptr) = unsafe { peek_poke::peek_from_default(v.as_ptr()) }; 31 let size = end_ptr as usize - v.as_ptr() as usize; 32 assert_eq!(size, v.len()); 33 assert_eq!(a, b); 34 } 35 36 #[test] 37 fn test_numbers() { 38 // unsigned positive 39 the_same(5u8); 40 the_same(5u16); 41 the_same(5u32); 42 the_same(5u64); 43 the_same(5usize); 44 // signed positive 45 the_same(5i8); 46 the_same(5i16); 47 the_same(5i32); 48 the_same(5i64); 49 the_same(5isize); 50 // signed negative 51 the_same(-5i8); 52 the_same(-5i16); 53 the_same(-5i32); 54 the_same(-5i64); 55 the_same(-5isize); 56 // floating 57 the_same(-100f32); 58 the_same(0f32); 59 the_same(5f32); 60 the_same(-100f64); 61 the_same(5f64); 62 } 63 64 #[test] 65 fn test_bool() { 66 the_same(true); 67 the_same(false); 68 } 69 70 #[test] 71 fn test_fixed_size_array() { 72 the_same([24u32; 32]); 73 the_same([1u64, 2, 3, 4, 5, 6, 7, 8]); 74 the_same([0u8; 19]); 75 } 76 77 #[test] 78 fn test_tuple() { 79 the_same((1isize, )); 80 the_same((1isize, 2isize, 3isize)); 81 the_same((1isize, ())); 82 } 83 84 #[test] 85 fn test_basic_struct() { 86 #[derive(Copy, Clone, Debug, Default, PartialEq, PeekPoke)] 87 struct Bar { 88 a: u32, 89 b: u32, 90 c: u32, 91 } 92 93 the_same(Bar { 94 a: 2, 95 b: 4, 96 c: 42, 97 }); 98 } 99 100 #[test] 101 fn test_enum() { 102 #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] 103 enum TestEnum { 104 NoArg, 105 OneArg(usize), 106 Args(usize, usize), 107 AnotherNoArg, 108 StructLike { x: usize, y: f32 }, 109 } 110 111 impl Default for TestEnum { 112 fn default() -> Self { 113 TestEnum::NoArg 114 } 115 } 116 117 the_same(TestEnum::NoArg); 118 the_same(TestEnum::OneArg(4)); 119 the_same(TestEnum::Args(4, 5)); 120 the_same(TestEnum::AnotherNoArg); 121 the_same(TestEnum::StructLike { x: 4, y: 3.14159 }); 122 } 123 124 #[test] 125 fn test_enum_cstyle() { 126 #[repr(u32)] 127 #[derive(Clone, Copy, Debug, PartialEq, Eq, PeekPoke)] 128 enum BorderStyle { 129 None = 0, 130 Solid = 1, 131 Double = 2, 132 Dotted = 3, 133 Dashed = 4, 134 Hidden = 5, 135 Groove = 6, 136 Ridge = 7, 137 Inset = 8, 138 Outset = 9, 139 } 140 141 impl Default for BorderStyle { 142 fn default() -> Self { 143 BorderStyle::None 144 } 145 } 146 147 the_same(BorderStyle::None); 148 the_same(BorderStyle::Solid); 149 the_same(BorderStyle::Double); 150 the_same(BorderStyle::Dotted); 151 the_same(BorderStyle::Dashed); 152 the_same(BorderStyle::Hidden); 153 the_same(BorderStyle::Groove); 154 the_same(BorderStyle::Ridge); 155 the_same(BorderStyle::Inset); 156 the_same(BorderStyle::Outset); 157 } 158 159 #[test] 160 fn test_phantom_data() { 161 struct Bar; 162 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PeekPoke)] 163 struct Foo { 164 x: u32, 165 y: u32, 166 _marker: PhantomData<Bar>, 167 } 168 the_same(Foo { 169 x: 19, 170 y: 42, 171 _marker: PhantomData, 172 }); 173 } 174 175 #[test] 176 fn test_generic() { 177 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PeekPoke)] 178 struct Foo<T> { 179 x: T, 180 y: T, 181 } 182 the_same(Foo { x: 19.0, y: 42.0 }); 183 } 184 185 #[test] 186 fn test_generic_enum() { 187 #[derive(Clone, Copy, Debug, Default, PartialEq, PeekPoke)] 188 #[allow(dead_code)] 189 pub struct PropertyBindingKey<T> { 190 pub id: usize, 191 _phantom: PhantomData<T>, 192 } 193 194 #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] 195 #[allow(dead_code)] 196 pub enum PropertyBinding<T> { 197 Value(T), 198 Binding(PropertyBindingKey<T>, T), 199 } 200 201 impl<T: Default> Default for PropertyBinding<T> { 202 fn default() -> Self { 203 PropertyBinding::Value(Default::default()) 204 } 205 } 206 }