Skip to main content

tablo_core/column/
file.rs

1//! [`FileColumn`]: an uploaded file's path rendered as a link to the file.
2
3use derive_where::derive_where;
4use topcoat::{context::Cx, view::*};
5
6use super::{Column, ColumnBase, ColumnWidth};
7use crate::Lens;
8
9/// A column of a `String` field holding an uploaded file's path, rendered as a link to the file.
10///
11/// ```rust
12/// # #[derive(Debug, Clone, toasty::Model, tablo_core::ModelColumns)]
13/// # struct Doc { #[key] #[auto] id: uuid::Uuid, path: String }
14/// tablo_core::FileColumn::new(tablo_core::lens!(Doc.path));
15/// ```
16///
17/// The cell links a rooted path or an absolute `http(s)` URL, the same rule a
18/// [`Field::file`](crate::Field::file) control applies, and shows any other value as text.
19#[derive_where(Clone, Debug)]
20pub struct FileColumn<M> {
21    lens: Lens<M, String>,
22    base: ColumnBase,
23}
24
25impl<M> FileColumn<M>
26where
27    M: toasty::schema::Model,
28{
29    /// Bind the column to the `String` field `lens` reads.
30    pub fn new(lens: Lens<M, String>) -> Self {
31        Self {
32            base: ColumnBase::new(lens.path(), ColumnWidth::Grow),
33            lens,
34        }
35    }
36
37    base_builders!();
38}
39
40impl<M> Column<M> for FileColumn<M>
41where
42    M: toasty::schema::Model + Send + Sync + 'static,
43{
44    base_column_methods!(binding);
45
46    fn text(&self, _cx: &Cx, row: &M) -> String {
47        self.lens.read(row).clone()
48    }
49
50    fn cell<'a>(&self, cx: &'a Cx, row: &M) -> BoxView<'a> {
51        let path = self.lens.read(row);
52        if path.trim().is_empty() {
53            return crate::schema::value_cell(cx, path);
54        }
55        crate::schema::stored_upload(cx, path)
56    }
57}