Skip to main content

Panel

Struct Panel 

Source
pub struct Panel {
    pub id: String,
    pub kind: PanelKind,
    pub namespace: String,
    pub props: Props,
    pub rows: Vec<Vec<Value>>,
    pub source: Option<PanelSource>,
    pub fields: Vec<Field>,
    pub children: Vec<Panel>,
    pub published: bool,
}
Expand description

A resolved panel: definition facts plus whatever rows were loaded for it.

Fields§

§id: String§kind: PanelKind§namespace: String§props: Props

panel_prop(Id, Key, Value) pairs, values as sent.

§rows: Vec<Vec<Value>>

Rows: either the live panel_source result or the panel_data snapshot. Resolution happens outside this crate — see PanelSource.

§source: Option<PanelSource>§fields: Vec<Field>

Form fields — parts of a form panel.

§children: Vec<Panel>

Child panels — parts of a dashboard (or any non-form container).

§published: bool

Whether the publisher marked this panel published.

Matches the server: published must be true (or "true"); an absent prop means not published.

Implementations§

Source§

impl Panel

Source

pub fn all_from_facts(facts: &PanelFacts) -> Vec<Panel>

Build every panel present in facts.

Parts (form fields, dashboard children) are folded into their container and removed from the top-level result, so callers get panels, not panels-and-their-parts.

Examples found in repository?
examples/parse_fixture.rs (line 54)
18fn main() {
19    let path = std::env::args()
20        .nth(1)
21        .expect("usage: parse_fixture <facts.json>");
22    let raw = std::fs::read_to_string(&path).expect("read fixture");
23    let doc: BTreeMap<String, Value> =
24        serde_json::from_str(&raw).expect("fixture is a JSON object");
25
26    let rows = |key: &str| -> Vec<Value> {
27        doc.get(key)
28            .and_then(Value::as_array)
29            .cloned()
30            .unwrap_or_default()
31    };
32
33    let facts = PanelFacts {
34        panels: rows("panels"),
35        props: rows("props"),
36        data: rows("data"),
37        sources: rows("sources"),
38        field_inputs: rows("field_inputs"),
39        field_triggers: rows("field_triggers"),
40        field_emits: rows("field_emits"),
41    };
42
43    println!(
44        "input rows: panels={} props={} data={} sources={} fields(in/trig/emit)={}/{}/{}",
45        facts.panels.len(),
46        facts.props.len(),
47        facts.data.len(),
48        facts.sources.len(),
49        facts.field_inputs.len(),
50        facts.field_triggers.len(),
51        facts.field_emits.len()
52    );
53
54    let panels = Panel::all_from_facts(&facts);
55    println!("parsed panels: {}\n", panels.len());
56
57    let mut unknown = 0;
58    for p in &panels {
59        let kind = p.kind.as_str().to_string();
60        if matches!(p.kind, datagrout_panels::PanelKind::Unknown(_)) {
61            unknown += 1;
62        }
63        println!(
64            "{:<24} {:<11} ns={:<20} props={:<2} rows={:<3} cols={:<2} source={} fields={} children={} published={}",
65            p.id,
66            kind,
67            p.namespace,
68            p.props.len(),
69            p.rows.len(),
70            p.rows.first().map(Vec::len).unwrap_or(0),
71            p.source.is_some(),
72            p.fields.len(),
73            p.children.len(),
74            p.published
75        );
76        for c in &p.children {
77            println!(
78                "    └ {:<20} {:<11} rows={:<3} columns={:?}",
79                c.id,
80                c.kind.as_str(),
81                c.rows.len(),
82                c.columns()
83            );
84        }
85    }
86
87    // Anything a renderer would fall back on is worth calling out by name.
88    println!("\nunknown kinds: {unknown}");
89    let titled = panels
90        .iter()
91        .filter(|p| p.props.contains_key("title"))
92        .count();
93    println!("panels with a title prop: {titled}/{}", panels.len());
94}
Source

pub fn from_facts(facts: &PanelFacts, id: &str) -> Option<Panel>

Build a single panel by id, or None if it is absent.

Source

pub fn all_from_list(response: &Value) -> Vec<Panel>

Build every panel from a smart_panel.list response.

Accepts either the whole response ({"panels": [...]}) or the bare array. Each entry carries id, kind, namespace, props, and optionally data_preview, source_info and field_ids.

Rows are a preview. data_preview holds at most the first few rows; a renderer that needs the full set still reads panel_data or runs the live source. Field-level metadata (field_input / field_trigger / field_emit) is not part of the list output and comes back empty.

Source§

impl Panel

Source

pub fn title(&self) -> String

Source

pub fn description(&self) -> Option<String>

Source

pub fn slot(&self) -> String

Layout slot hint. The server defaults this to "main".

Source

pub fn parent(&self) -> Option<String>

The container this panel is a part of, if any.

Source

pub fn columns(&self) -> Vec<String>

Column headers for table panels — the columns prop, a list.

Examples found in repository?
examples/parse_fixture.rs (line 82)
18fn main() {
19    let path = std::env::args()
20        .nth(1)
21        .expect("usage: parse_fixture <facts.json>");
22    let raw = std::fs::read_to_string(&path).expect("read fixture");
23    let doc: BTreeMap<String, Value> =
24        serde_json::from_str(&raw).expect("fixture is a JSON object");
25
26    let rows = |key: &str| -> Vec<Value> {
27        doc.get(key)
28            .and_then(Value::as_array)
29            .cloned()
30            .unwrap_or_default()
31    };
32
33    let facts = PanelFacts {
34        panels: rows("panels"),
35        props: rows("props"),
36        data: rows("data"),
37        sources: rows("sources"),
38        field_inputs: rows("field_inputs"),
39        field_triggers: rows("field_triggers"),
40        field_emits: rows("field_emits"),
41    };
42
43    println!(
44        "input rows: panels={} props={} data={} sources={} fields(in/trig/emit)={}/{}/{}",
45        facts.panels.len(),
46        facts.props.len(),
47        facts.data.len(),
48        facts.sources.len(),
49        facts.field_inputs.len(),
50        facts.field_triggers.len(),
51        facts.field_emits.len()
52    );
53
54    let panels = Panel::all_from_facts(&facts);
55    println!("parsed panels: {}\n", panels.len());
56
57    let mut unknown = 0;
58    for p in &panels {
59        let kind = p.kind.as_str().to_string();
60        if matches!(p.kind, datagrout_panels::PanelKind::Unknown(_)) {
61            unknown += 1;
62        }
63        println!(
64            "{:<24} {:<11} ns={:<20} props={:<2} rows={:<3} cols={:<2} source={} fields={} children={} published={}",
65            p.id,
66            kind,
67            p.namespace,
68            p.props.len(),
69            p.rows.len(),
70            p.rows.first().map(Vec::len).unwrap_or(0),
71            p.source.is_some(),
72            p.fields.len(),
73            p.children.len(),
74            p.published
75        );
76        for c in &p.children {
77            println!(
78                "    └ {:<20} {:<11} rows={:<3} columns={:?}",
79                c.id,
80                c.kind.as_str(),
81                c.rows.len(),
82                c.columns()
83            );
84        }
85    }
86
87    // Anything a renderer would fall back on is worth calling out by name.
88    println!("\nunknown kinds: {unknown}");
89    let titled = panels
90        .iter()
91        .filter(|p| p.props.contains_key("title"))
92        .count();
93    println!("panels with a title prop: {titled}/{}", panels.len());
94}
Source

pub fn prop_str(&self, key: &str) -> Option<String>

Read a prop as text. See prop_str.

Source

pub fn prop_list(&self, key: &str) -> Vec<String>

Read a prop as a list. See prop_list.

Source

pub fn prop_bool(&self, key: &str) -> Option<bool>

Read a prop as a boolean. See prop_bool.

Source

pub fn prop_f64(&self, key: &str) -> Option<f64>

Read a prop as a number. See prop_f64.

Trait Implementations§

Source§

impl Clone for Panel

Source§

fn clone(&self) -> Panel

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Panel

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Panel

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for Panel

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl Freeze for Panel

§

impl RefUnwindSafe for Panel

§

impl Send for Panel

§

impl Sync for Panel

§

impl Unpin for Panel

§

impl UnsafeUnpin for Panel

§

impl UnwindSafe for Panel

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.