1 // Copyright 2020-2021 Ian Jackson and contributors to Otter
2 // SPDX-License-Identifier: MIT-0 OR AGPL-3.0-or-later
3 // There is NO WARRANTY.
5 #![allow(clippy::or_fun_call)]
7 //! Provides a [`get_idx_key`](trait.KeyDataExt.html#tymethod.get_idx_version) method on
8 //! `slotmap::KeyData`. See [KeyDataExt::get_idx_version].
10 use crate::prelude::otter_base::misc::default;
12 /// Extension trait for `slotmap::KeyData`, providing `get_idx_version`.
14 /// No-one is expected to implement this trait for anything else.
15 pub trait KeyDataExt {
16 /// Returns the slot index and version. This is useful only in
17 /// unusual situations.
19 /// At any one time, a slotmap has at most one entry with each
20 /// index. The combination of index and version are unique across
21 /// time. Indices are generally not significantly bigger than thw
22 /// maximum ever occupancy. No other guarantees are made.
24 /// For serialisation, use `serde` or `as_ffi`.
28 /// This function panics if the `slotmap::KeyData` `serde::ser::Serialize`
29 /// representation has changed too much. This ought to be caught
30 /// by the tests, and would probably be a breaking change in the
31 /// underlying `slotmap` crate in any case.
33 /// If you prefer to receive an error rather than panicing,
34 /// see [keydata_extract].
35 fn get_idx_version(self) -> (u32, u32);
38 impl KeyDataExt for slotmap::KeyData {
39 fn get_idx_version(self) -> (u32, u32) {
40 keydata_extract(self).expect(
41 "slotmap KeyData Serialize representation changed!"
46 /// Underlying extraction function. Fails rather than panicing.
48 /// Fails if the `slotmap::KeyData` `serde::ser::Serialize`
49 /// representation has changed too much. Should not be able to fail
51 pub fn keydata_extract(key: slotmap::KeyData) -> Result<(u32, u32), Error> {
52 let mut m: MainExtractor = default();
53 key.serialize(&mut m)?;
54 Ok(( m.idx .ok_or(error(line!()))?,
55 m.version.ok_or(error(line!()))? ))
59 /// Problem with the `slotmap::KeyData` `Serialize` implementation.
61 /// Not really helpful. `Unexpected` gives the source line number
62 /// in `slotmap-slot-idx.rs`. `WasCustomSerialize` threw the
63 /// actual error away.
66 Unexpected(std::num::NonZeroU32),
68 impl std::error::Error for Error { }
70 //---------- implementation. avert your eyes ----------
72 use std::convert::TryFrom;
75 use serde::ser::{self, *};
78 struct MainExtractor {
83 struct ValueExtractor;
85 type R<Return> = Result<Return, Error>;
89 fn error(line: u32) -> Error { Unexpected(TryFrom::try_from(line).unwrap()) }
90 fn u<T>(line: u32) -> R<T> { Err(error(line)) }
92 type Imp = Impossible<(), Error>;
95 impl Serializer for &mut MainExtractor {
99 type SerializeStruct = Self;
101 type SerializeMap = Imp;
102 type SerializeSeq = Imp;
103 type SerializeTuple = Imp;
104 type SerializeTupleStruct = Imp;
105 type SerializeTupleVariant = Imp;
106 type SerializeStructVariant = Imp;
108 fn serialize_struct(self, _:&str, _: usize) -> R<Self> { Ok(self) }
110 fn serialize_bool (self, _: bool ) -> ROk { u(line!()) }
111 fn serialize_i8 (self, _: i8 ) -> ROk { u(line!()) }
112 fn serialize_i16 (self, _: i16 ) -> ROk { u(line!()) }
113 fn serialize_i32 (self, _: i32 ) -> ROk { u(line!()) }
114 fn serialize_i64 (self, _: i64 ) -> ROk { u(line!()) }
115 fn serialize_u8 (self, _: u8 ) -> ROk { u(line!()) }
116 fn serialize_u16 (self, _: u16 ) -> ROk { u(line!()) }
117 fn serialize_u32 (self, _: u32 ) -> ROk { u(line!()) }
118 fn serialize_u64 (self, _: u64 ) -> ROk { u(line!()) }
119 fn serialize_f32 (self, _: f32 ) -> ROk { u(line!()) }
120 fn serialize_f64 (self, _: f64 ) -> ROk { u(line!()) }
121 fn serialize_char (self, _: char ) -> ROk { u(line!()) }
122 fn serialize_str (self, _: &str ) -> ROk { u(line!()) }
123 fn serialize_bytes(self, _: &[u8 ]) -> ROk { u(line!()) }
124 fn serialize_none (self) -> ROk { u(line!()) }
125 fn serialize_unit (self) -> ROk { u(line!()) }
127 fn serialize_some<T>(self, _: &T) -> ROk
128 where T: Serialize + ?Sized { u(line!()) }
129 fn serialize_newtype_struct <T>(self, _:&str, _: &T) -> ROk
130 where T: Serialize + ?Sized { u(line!()) }
131 fn serialize_newtype_variant<T>(self, _:&str, _:u32, _:&str, _: &T) -> ROk
132 where T: Serialize + ?Sized { u(line!()) }
134 fn serialize_unit_struct (self,_:&str ) -> ROk { u(line!()) }
135 fn serialize_unit_variant(self,_:&str,_:u32,_:&str) -> ROk { u(line!()) }
136 fn serialize_seq (self,_:Option<usize> ) -> RI { u(line!()) }
137 fn serialize_tuple (self,_:usize ) -> RI { u(line!()) }
138 fn serialize_tuple_struct(self,_:&str, _:usize ) -> RI { u(line!()) }
139 fn serialize_map (self,_:Option<usize> ) -> RI { u(line!()) }
140 fn serialize_tuple_variant (self,_:&str,_:u32,_:&str,_:usize)->RI{u(line!())}
141 fn serialize_struct_variant(self,_:&str,_:u32,_:&str,_:usize)->RI{u(line!())}
144 impl SerializeStruct for &mut MainExtractor {
148 fn serialize_field<T: Serialize + ?Sized> (
149 &mut self, key: &str, value: &T
151 if key == "idx" { self.idx = Some(value.serialize(ValueExtractor)?); }
152 if key == "version" { self.version = Some(value.serialize(ValueExtractor)?); }
156 fn end(self) -> ROk { Ok(()) }
160 type ImpV = Impossible<V,Error>;
163 impl Serializer for ValueExtractor {
167 fn serialize_u32(self, value: u32) -> R<V> { Ok(value) }
169 type SerializeStruct = ImpV;
170 type SerializeMap = ImpV;
171 type SerializeSeq = ImpV;
172 type SerializeTuple = ImpV;
173 type SerializeTupleStruct = ImpV;
174 type SerializeTupleVariant = ImpV;
175 type SerializeStructVariant = ImpV;
177 fn serialize_bool (self, _: bool ) -> R<V> { u(line!()) }
178 fn serialize_i8 (self, _: i8 ) -> R<V> { u(line!()) }
179 fn serialize_i16 (self, _: i16 ) -> R<V> { u(line!()) }
180 fn serialize_i32 (self, _: i32 ) -> R<V> { u(line!()) }
181 fn serialize_i64 (self, _: i64 ) -> R<V> { u(line!()) }
182 fn serialize_u8 (self, _: u8 ) -> R<V> { u(line!()) }
183 fn serialize_u16 (self, _: u16 ) -> R<V> { u(line!()) }
184 fn serialize_u64 (self, _: u64 ) -> R<V> { u(line!()) }
185 fn serialize_f32 (self, _: f32 ) -> R<V> { u(line!()) }
186 fn serialize_f64 (self, _: f64 ) -> R<V> { u(line!()) }
187 fn serialize_char (self, _: char ) -> R<V> { u(line!()) }
188 fn serialize_str (self, _: &str ) -> R<V> { u(line!()) }
189 fn serialize_bytes(self, _: &[u8 ]) -> R<V> { u(line!()) }
190 fn serialize_none (self) -> R<V> { u(line!()) }
191 fn serialize_unit (self) -> R<V> { u(line!()) }
193 fn serialize_some <T>(self, _: &T) -> R<V>
194 where T: Serialize + ?Sized { u(line!()) }
195 fn serialize_newtype_struct <T>(self, _:&str, _: &T) -> R<V>
196 where T: Serialize + ?Sized { u(line!()) }
197 fn serialize_newtype_variant<T>(self, _:&str, _:u32, _:&str, _: &T) -> R<V>
198 where T: Serialize + ?Sized { u(line!()) }
200 fn serialize_unit_struct (self,_:&str ) -> R<V> { u(line!()) }
201 fn serialize_unit_variant (self,_:&str,_:u32,_:&str) -> R<V> { u(line!()) }
202 fn serialize_seq (self,_:Option<usize> ) -> RIV { u(line!()) }
203 fn serialize_tuple (self,_:usize ) -> RIV { u(line!()) }
204 fn serialize_tuple_struct (self,_:&str, _: usize ) -> RIV { u(line!()) }
205 fn serialize_struct (self,_:&str, _: usize ) -> RIV { u(line!()) }
206 fn serialize_map (self,_:Option<usize> ) -> RIV { u(line!()) }
207 fn serialize_tuple_variant (self,_:&str,_:u32,_:&str,_:usize)->RIV{u(line!())}
208 fn serialize_struct_variant(self,_:&str,_:u32,_:&str,_:usize)->RIV{u(line!())}
211 impl ser::Error for Error {
212 fn custom<T>(_msg: T) -> Self { Error::WasCustomSerialize }
215 impl fmt::Display for Error {
216 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
217 fmt::Debug::fmt(self,f)
224 let kd = slotmap::KeyData::from_ffi(v);
225 let v = kd.as_ffi(); // KeyData is not transparent for all u64
226 let (idx,vsn) = self::KeyDataExt::get_idx_version(kd);
227 eprintln!("KeyData={:?} v=0x{:x?} idx={}=0x{:x} vsn={}=0x{:x}",
228 &kd, &v, idx,idx, vsn,vsn);
229 assert_eq!(v, ((vsn as u64) << 32) | (idx as u64));
231 t(0x0123456789abcdef);
232 t(0xfedcba9876543210);
234 t(0xffffffff12345678);
235 t(0x12345678ffffffff);
236 t(0xffffffff00000000);
237 t(0x00000000ffffffff);
238 t(0x0000000012345678);
239 t(0x1234567800000000);