diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..4d7dd9e --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,3 @@ +imports_granularity = "Crate" +newline_style = "Unix" +group_imports = "StdExternalCrate" \ No newline at end of file diff --git a/src/strategy.rs b/src/strategy.rs new file mode 100644 index 0000000..aba4950 --- /dev/null +++ b/src/strategy.rs @@ -0,0 +1,46 @@ +use core::marker::PhantomData; + +use stuff::Backend; + +pub trait SafeStuffingStrategy { + type Extra; + + fn stuff_extra(extra: &Self::Extra) -> B; + + fn extract_extra(addr: B) -> Option; +} + +/// An internal type to convert from the safe to the unsafe trait +pub(crate) struct SafeStrategyAdaptor(PhantomData); + +// SAFETY: `extract_extra` panics if an invalid extra is returned +// `stuff_extra` never drops the extra +// pointer stuffing is just identity +unsafe impl stuff::StuffingStrategy for SafeStrategyAdaptor +where + S: SafeStuffingStrategy, +{ + type Extra = S::Extra; + + fn is_extra(data: B) -> bool { + S::extract_extra(data).is_some() + } + + fn stuff_extra(inner: Self::Extra) -> B { + let b = S::stuff_extra(&inner); + core::mem::forget(inner); + b + } + + unsafe fn extract_extra(data: B) -> Self::Extra { + S::extract_extra(data).unwrap() + } + + fn stuff_ptr(addr: usize) -> B { + addr + } + + fn extract_ptr(inner: B) -> usize { + inner + } +}