leptos_struct_table/
cell_value.rs

1use leptos::prelude::*;
2
3#[derive(Default, Clone, Copy)]
4pub struct NumberRenderOptions {
5    /// Specifies the number of digits to display after the decimal point
6    pub precision: Option<usize>,
7}
8
9/// A value that can be rendered as part of a table, required for types if the [`crate::DefaultTableCellRenderer()`] is used
10pub trait CellValue<M: ?Sized = ()> {
11    /// Formatting options for this cell value type, needs to implement default and have public named fields,
12    /// the empty tuple: () is fine if no formatting options can be accepted.
13    type RenderOptions: Default + Clone + Send + Sync + 'static;
14
15    /// This is called to actually render the value. The parameter `options` is filled by the `#[table(format(...))]` macro attribute or `Default::default()` if omitted.
16    fn render_value(self, options: Self::RenderOptions) -> impl IntoView;
17}
18
19impl<V> CellValue<()> for V
20where
21    V: IntoView,
22{
23    type RenderOptions = ();
24
25    fn render_value(self, _options: Self::RenderOptions) -> impl IntoView {
26        self
27    }
28}
29
30macro_rules! viewable_primitive {
31  ($($child_type:ty),* $(,)?) => {
32    $(
33      impl CellValue<$child_type> for $child_type {
34        type RenderOptions = ();
35
36        #[inline(always)]
37        fn render_value(self, _options: Self::RenderOptions) -> impl IntoView {
38            self.to_string()
39        }
40      }
41    )*
42  };
43}
44
45viewable_primitive![
46    &String,
47    char,
48    bool,
49    std::net::IpAddr,
50    std::net::SocketAddr,
51    std::net::SocketAddrV4,
52    std::net::SocketAddrV6,
53    std::net::Ipv4Addr,
54    std::net::Ipv6Addr,
55    std::char::ToUppercase,
56    std::char::ToLowercase,
57    std::num::NonZeroI8,
58    std::num::NonZeroU8,
59    std::num::NonZeroI16,
60    std::num::NonZeroU16,
61    std::num::NonZeroI32,
62    std::num::NonZeroU32,
63    std::num::NonZeroI64,
64    std::num::NonZeroU64,
65    std::num::NonZeroI128,
66    std::num::NonZeroU128,
67    std::num::NonZeroIsize,
68    std::num::NonZeroUsize,
69    std::panic::Location<'_>,
70];
71
72macro_rules! viewable_number_primitive {
73  ($($child_type:ty),* $(,)?) => {
74    $(
75      impl CellValue<$child_type> for $child_type {
76        type RenderOptions = NumberRenderOptions;
77
78        #[inline(always)]
79        fn render_value(self, options: Self::RenderOptions) -> impl IntoView {
80        if let Some(value) = options.precision.as_ref() {
81            view! {
82                <>{format!("{:.value$}", self)}</>
83            }
84        }
85        else {
86            view! {
87                <>{self.to_string()}</>
88            }
89        }
90        }
91      }
92    )*
93  };
94}
95
96viewable_number_primitive![
97    usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64,
98];