Radish alpha
r
rad:z39mP9rQAaGmERfUMPULfPUi473tY
Radicle terminal user interface
Radicle
Git
lib: Make table width constant
Merged did:key:z6MkgFq6...nBGz opened 2 years ago

Performance improvement: Tables have constant column count.

5 files changed +25 -28 beaf1af2 222da206
modified bin/commands/inbox/select/ui.rs
@@ -149,7 +149,7 @@ impl<'a: 'static> Widget for BrowsePage<'a> {
                        .focus(props.focus)
                        .to_boxed(),
                )
-
                .content(Box::<Table<State, Action, NotificationItem>>::new(
+
                .content(Box::<Table<State, Action, NotificationItem, 9>>::new(
                    Table::new(state, action_tx.clone())
                        .on_event(|table, action_tx| {
                            TableState::from_boxed_any(table).and_then(|table| {
modified bin/commands/issue/select/ui.rs
@@ -154,7 +154,7 @@ impl<'a: 'static> Widget for BrowsePage<'a> {
                        .focus(props.focus)
                        .to_boxed(),
                )
-
                .content(Box::<Table<State, Action, IssueItem>>::new(
+
                .content(Box::<Table<State, Action, IssueItem, 8>>::new(
                    Table::new(state, action_tx.clone())
                        .on_event(|table, action_tx| {
                            TableState::from_boxed_any(table).and_then(|table| {
modified bin/commands/patch/select/ui.rs
@@ -153,7 +153,7 @@ impl<'a: 'static> Widget for BrowsePage<'a> {
                        .focus(props.focus)
                        .to_boxed(),
                )
-
                .content(Box::<Table<State, Action, PatchItem>>::new(
+
                .content(Box::<Table<State, Action, PatchItem, 9>>::new(
                    Table::new(state, action_tx.clone())
                        .on_event(|table, action_tx| {
                            TableState::from_boxed_any(table).and_then(|table| {
modified src/ui/items.rs
@@ -213,8 +213,8 @@ impl NotificationItem {
    }
}

-
impl ToRow for NotificationItem {
-
    fn to_row(&self) -> Vec<Cell> {
+
impl ToRow<9> for NotificationItem {
+
    fn to_row(&self) -> [Cell; 9] {
        let (type_name, summary, status, kind_id) = match &self.kind {
            NotificationKindItem::Branch {
                name,
@@ -294,7 +294,6 @@ impl ToRow for NotificationItem {
            author.into(),
            timestamp.into(),
        ]
-
        .to_vec()
    }
}

@@ -488,8 +487,8 @@ impl IssueItem {
    }
}

-
impl ToRow for IssueItem {
-
    fn to_row(&self) -> Vec<Cell> {
+
impl ToRow<8> for IssueItem {
+
    fn to_row(&self) -> [Cell; 8] {
        let (state, state_color) = format::issue_state(&self.state);

        let state = span::default(&state).style(Style::default().fg(state_color));
@@ -532,7 +531,6 @@ impl ToRow for IssueItem {
            assignees.into(),
            opened.into(),
        ]
-
        .to_vec()
    }
}

@@ -740,8 +738,8 @@ impl PatchItem {
    }
}

-
impl ToRow for PatchItem {
-
    fn to_row(&self) -> Vec<Cell> {
+
impl ToRow<9> for PatchItem {
+
    fn to_row(&self) -> [Cell; 9] {
        let (state, color) = format::patch_state(&self.state);

        let state = span::default(&state).style(Style::default().fg(color));
@@ -782,7 +780,6 @@ impl ToRow for PatchItem {
            removed.into(),
            updated.into(),
        ]
-
        .to_vec()
    }
}

modified src/ui/widget.rs
@@ -100,8 +100,8 @@ pub trait Widget {
}

/// Needs to be implemented for items that are supposed to be rendered in tables.
-
pub trait ToRow {
-
    fn to_row(&self) -> Vec<Cell>;
+
pub trait ToRow<const W: usize> {
+
    fn to_row(&self) -> [Cell; W];
}

/// Common trait for view properties.
@@ -404,9 +404,9 @@ impl<'a> Column<'a> {
}

#[derive(Clone, Debug)]
-
pub struct TableProps<'a, R>
+
pub struct TableProps<'a, R, const W: usize>
where
-
    R: ToRow,
+
    R: ToRow<W>,
{
    pub items: Vec<R>,
    pub selected: Option<usize>,
@@ -418,9 +418,9 @@ where
    pub page_size: usize,
}

-
impl<'a, R> Default for TableProps<'a, R>
+
impl<'a, R, const W: usize> Default for TableProps<'a, R, W>
where
-
    R: ToRow,
+
    R: ToRow<W>,
{
    fn default() -> Self {
        Self {
@@ -436,9 +436,9 @@ where
    }
}

-
impl<'a, R> TableProps<'a, R>
+
impl<'a, R, const W: usize> TableProps<'a, R, W>
where
-
    R: ToRow,
+
    R: ToRow<W>,
{
    pub fn items(mut self, items: Vec<R>) -> Self {
        self.items = items;
@@ -472,24 +472,24 @@ where
    }
}

-
impl<'a: 'static, R> Properties for TableProps<'a, R> where R: ToRow + 'static {}
+
impl<'a: 'static, R, const W: usize> Properties for TableProps<'a, R, W> where R: ToRow<W> + 'static {}
impl WidgetState for TableState {}

-
pub struct Table<'a, S, A, R>
+
pub struct Table<'a, S, A, R, const W: usize>
where
-
    R: ToRow,
+
    R: ToRow<W>,
{
    /// Internal base
    base: BaseView<S, A>,
    /// Internal table properties
-
    props: TableProps<'a, R>,
+
    props: TableProps<'a, R, W>,
    /// Internal selection and offset state
    state: TableState,
}

-
impl<'a, S, A, R> Table<'a, S, A, R>
+
impl<'a, S, A, R, const W: usize> Table<'a, S, A, R, W>
where
-
    R: ToRow,
+
    R: ToRow<W>,
{
    fn prev(&mut self) -> Option<usize> {
        let selected = self
@@ -542,9 +542,9 @@ where
    }
}

-
impl<'a: 'static, S, A, R> Widget for Table<'a, S, A, R>
+
impl<'a: 'static, S, A, R, const W: usize> Widget for Table<'a, S, A, R, W>
where
-
    R: ToRow + Clone + 'static,
+
    R: ToRow<W> + Clone + 'static,
{
    type Action = A;
    type State = S;