xref: /linux/rust/kernel/debugfs/callback_adapters.rs (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2025 Google LLC.
3 
4 //! Adapters which allow the user to supply a write or read implementation as a value rather
5 //! than a trait implementation. If provided, it will override the trait implementation.
6 
7 use super::{Reader, Writer};
8 use crate::prelude::*;
9 use crate::uaccess::UserSliceReader;
10 use core::fmt;
11 use core::fmt::Formatter;
12 use core::marker::PhantomData;
13 use core::ops::Deref;
14 
15 /// # Safety
16 ///
17 /// To implement this trait, it must be safe to cast a `&Self` to a `&Inner`.
18 /// It is intended for use in unstacking adapters out of `FileOps` backings.
19 pub(crate) unsafe trait Adapter {
20     type Inner;
21 }
22 
23 /// Adapter to implement `Reader` via a callback with the same representation as `T`.
24 ///
25 /// * Layer it on top of `WriterAdapter` if you want to add a custom callback for `write`.
26 /// * Layer it on top of `NoWriter` to pass through any support present on the underlying type.
27 ///
28 /// # Invariants
29 ///
30 /// If an instance for `WritableAdapter<_, W>` is constructed, `W` is inhabited.
31 #[repr(transparent)]
32 pub(crate) struct WritableAdapter<D, W> {
33     inner: D,
34     _writer: PhantomData<W>,
35 }
36 
37 // SAFETY: Stripping off the adapter only removes constraints
38 unsafe impl<D, W> Adapter for WritableAdapter<D, W> {
39     type Inner = D;
40 }
41 
42 impl<D: Writer, W> Writer for WritableAdapter<D, W> {
43     fn write(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
44         self.inner.write(fmt)
45     }
46 }
47 
48 impl<D: Deref, W> Reader for WritableAdapter<D, W>
49 where
50     W: Fn(&D::Target, &mut UserSliceReader) -> Result + Send + Sync + 'static,
51 {
52     fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
53         // SAFETY: WritableAdapter<_, W> can only be constructed if W is inhabited
54         let w: &W = unsafe { materialize_zst() };
55         w(self.inner.deref(), reader)
56     }
57 }
58 
59 /// Adapter to implement `Writer` via a callback with the same representation as `T`.
60 ///
61 /// # Invariants
62 ///
63 /// If an instance for `FormatAdapter<_, F>` is constructed, `F` is inhabited.
64 #[repr(transparent)]
65 pub(crate) struct FormatAdapter<D, F> {
66     inner: D,
67     _formatter: PhantomData<F>,
68 }
69 
70 impl<D, F> Deref for FormatAdapter<D, F> {
71     type Target = D;
72     fn deref(&self) -> &D {
73         &self.inner
74     }
75 }
76 
77 impl<D, F> Writer for FormatAdapter<D, F>
78 where
79     F: Fn(&D, &mut Formatter<'_>) -> fmt::Result + 'static,
80 {
81     fn write(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
82         // SAFETY: FormatAdapter<_, F> can only be constructed if F is inhabited
83         let f: &F = unsafe { materialize_zst() };
84         f(&self.inner, fmt)
85     }
86 }
87 
88 // SAFETY: Stripping off the adapter only removes constraints
89 unsafe impl<D, F> Adapter for FormatAdapter<D, F> {
90     type Inner = D;
91 }
92 
93 #[repr(transparent)]
94 pub(crate) struct NoWriter<D> {
95     inner: D,
96 }
97 
98 // SAFETY: Stripping off the adapter only removes constraints
99 unsafe impl<D> Adapter for NoWriter<D> {
100     type Inner = D;
101 }
102 
103 impl<D> Deref for NoWriter<D> {
104     type Target = D;
105     fn deref(&self) -> &D {
106         &self.inner
107     }
108 }
109 
110 /// For types with a unique value, produce a static reference to it.
111 ///
112 /// # Safety
113 ///
114 /// The caller asserts that F is inhabited
115 unsafe fn materialize_zst<F>() -> &'static F {
116     const { assert!(core::mem::size_of::<F>() == 0) };
117     let zst_dangle: core::ptr::NonNull<F> = core::ptr::NonNull::dangling();
118     // SAFETY: While the pointer is dangling, it is a dangling pointer to a ZST, based on the
119     // assertion above. The type is also inhabited, by the caller's assertion. This means
120     // we can materialize it.
121     unsafe { zst_dangle.as_ref() }
122 }
123