Skip to main content

oino_ui/extras/
log.rs

1//! `Log` node (§4.5.2).
2
3use serde::{Deserialize, Serialize};
4
5use crate::node::{Common, IntoNode, Node};
6use crate::text::Line;
7
8/// A tailing log (§4.5.2). `lines` is a ring of `maxLines`; older lines are
9/// dropped silently (§4.8). Follow pauses when the user scrolls up.
10#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct Log {
13    /// Common node props (`key`, `style`, `block`, `fallback`).
14    #[serde(flatten)]
15    pub common: Common,
16    /// Log lines (ring-trimmed to `maxLines`).
17    pub lines: Vec<Line>,
18    /// Ring capacity (default 2 000, ≤ 5 000).
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub max_lines: Option<u32>,
21    /// Stick to the tail (default `true`).
22    #[serde(default, skip_serializing_if = "Option::is_none")]
23    pub follow: Option<bool>,
24    /// Wrap long lines (default `false`).
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub wrap: Option<bool>,
27    /// Render line numbers.
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub line_numbers: Option<bool>,
30}
31
32impl Log {
33    /// A log from lines.
34    #[must_use]
35    pub fn new(lines: impl IntoIterator<Item = impl Into<Line>>) -> Self {
36        Self {
37            lines: lines.into_iter().map(Into::into).collect(),
38            ..Self::default()
39        }
40    }
41
42    /// Appends lines (the wire keeps ≤ `maxLines`, §4.8).
43    #[must_use]
44    pub fn lines(mut self, lines: impl IntoIterator<Item = impl Into<Line>>) -> Self {
45        self.lines.extend(lines.into_iter().map(Into::into));
46        self
47    }
48
49    /// Sets the ring capacity.
50    #[must_use]
51    pub fn max_lines(mut self, max_lines: u32) -> Self {
52        self.max_lines = Some(max_lines);
53        self
54    }
55
56    /// Sets tail following.
57    #[must_use]
58    pub fn follow(mut self, follow: bool) -> Self {
59        self.follow = Some(follow);
60        self
61    }
62
63    /// Wraps long lines.
64    #[must_use]
65    pub fn wrap(mut self, wrap: bool) -> Self {
66        self.wrap = Some(wrap);
67        self
68    }
69
70    /// Renders line numbers.
71    #[must_use]
72    pub fn line_numbers(mut self, line_numbers: bool) -> Self {
73        self.line_numbers = Some(line_numbers);
74        self
75    }
76}
77
78impl IntoNode for Log {}
79impl From<Log> for Node {
80    fn from(l: Log) -> Self {
81        Node::Log(l)
82    }
83}