reactive_graph_table_model/types/
extension.rs

1use std::fmt;
2use std::fmt::Formatter;
3use std::ops::Deref;
4
5use serde_json::Value;
6use table_to_html::HtmlTable;
7use tabled::Table;
8use tabled::Tabled;
9use tabled::settings::Modify;
10use tabled::settings::Style;
11use tabled::settings::Width;
12use tabled::settings::object::Columns;
13
14use crate::container::TableInlineFormat;
15use crate::container::TableInlineFormatSetter;
16use crate::container::TableOptions;
17use crate::styles::modern_inline::modern_inline;
18use crate::types::json_value::pretty_json;
19use reactive_graph_graph::NamespacedTypeGetter;
20
21#[derive(Clone, Debug, Tabled)]
22pub struct ExtensionTypeId {
23    pub name: String,
24    pub namespace: String,
25}
26
27impl From<reactive_graph_graph::ExtensionTypeId> for ExtensionTypeId {
28    fn from(ty: reactive_graph_graph::ExtensionTypeId) -> Self {
29        ExtensionTypeId {
30            name: ty.type_name(),
31            namespace: ty.namespace(),
32        }
33    }
34}
35
36pub struct ExtensionDefinition {
37    pub type_: ExtensionTypeId,
38    pub description: String,
39    pub extension: Value,
40}
41
42impl From<reactive_graph_graph::Extension> for ExtensionDefinition {
43    fn from(extension: reactive_graph_graph::Extension) -> Self {
44        ExtensionDefinition {
45            type_: extension.ty.into(),
46            description: extension.description,
47            extension: extension.extension,
48        }
49    }
50}
51
52pub fn display_extensions_inline_str(extensions: &[Extension]) -> String {
53    if extensions.is_empty() {
54        String::new()
55    } else {
56        display_extensions_inline(extensions).to_string()
57    }
58}
59
60pub fn display_extensions_inline(extensions: &[Extension]) -> Table {
61    let extensions = extensions.to_vec();
62    Table::new(extensions)
63        .with(modern_inline())
64        .with(Modify::new(Columns::new(0..1)).with(Width::increase(22)))
65        .with(Modify::new(Columns::new(1..2)).with(Width::increase(22)))
66        .with(Modify::new(Columns::new(2..3)).with(Width::wrap(40)))
67        .with(Modify::new(Columns::new(3..4)).with(Width::wrap(80)))
68        .to_owned()
69}
70
71pub fn display_extensions_html_inline(extensions: &[Extension]) -> String {
72    let extensions = extensions.to_vec();
73    if extensions.is_empty() {
74        return String::new();
75    }
76    HtmlTable::with_header(Vec::<Vec<String>>::from(Table::builder(&extensions)))
77        .to_string()
78        .split_whitespace()
79        .collect()
80}
81
82pub struct ExtensionDefinitions(pub Vec<ExtensionDefinition>);
83
84impl From<ExtensionDefinitions> for Vec<ExtensionDefinition> {
85    fn from(extensions: ExtensionDefinitions) -> Self {
86        extensions.0.into_iter().collect()
87    }
88}
89
90impl From<reactive_graph_graph::Extensions> for ExtensionDefinitions {
91    fn from(extensions: reactive_graph_graph::Extensions) -> Self {
92        ExtensionDefinitions(extensions.into_iter().map(|(_extension_ty, extension)| extension.into()).collect())
93    }
94}
95
96#[derive(Clone, Debug, Tabled)]
97pub struct Extension {
98    /// The namespace of the extension.
99    #[tabled(rename = "Namespace")]
100    pub namespace: String,
101
102    /// The name of the extension.
103    #[tabled(rename = "Type Name")]
104    pub name: String,
105
106    /// Textual description of the extension.
107    #[tabled(rename = "Description")]
108    pub description: String,
109
110    /// The extension as JSON representation.
111    #[tabled(rename = "Extension", display("pretty_json"))]
112    pub extension: Value,
113
114    #[tabled(skip)]
115    inline_format: TableInlineFormat,
116}
117
118impl TableInlineFormatSetter for Extension {
119    fn set_table_inline_format(&mut self, table_inline_format: TableInlineFormat) {
120        self.inline_format = table_inline_format;
121    }
122}
123
124impl From<Extension> for reactive_graph_graph::Extension {
125    fn from(extension: Extension) -> Self {
126        let ty = reactive_graph_graph::ExtensionTypeId::new_from_type(extension.namespace, extension.name);
127        reactive_graph_graph::Extension {
128            ty,
129            description: extension.description,
130            extension: extension.extension,
131        }
132    }
133}
134
135impl From<reactive_graph_graph::Extension> for Extension {
136    fn from(extension: reactive_graph_graph::Extension) -> Self {
137        Extension {
138            namespace: extension.namespace(),
139            name: extension.type_name(),
140            description: extension.description,
141            extension: extension.extension,
142            inline_format: Default::default(),
143        }
144    }
145}
146
147#[derive(Clone, Debug)]
148pub struct Extensions(pub Vec<Extension>);
149
150impl Deref for Extensions {
151    type Target = Vec<Extension>;
152
153    fn deref(&self) -> &Self::Target {
154        &self.0
155    }
156}
157
158impl From<Extensions> for reactive_graph_graph::Extensions {
159    fn from(extensions: Extensions) -> Self {
160        extensions.0.into_iter().map(|extension| extension.into()).collect()
161    }
162}
163
164impl From<Extensions> for Vec<Extension> {
165    fn from(extensions: Extensions) -> Self {
166        extensions.0
167    }
168}
169
170impl From<reactive_graph_graph::Extensions> for Extensions {
171    fn from(extensions: reactive_graph_graph::Extensions) -> Self {
172        Extensions(extensions.into_iter().map(|(_extension_ty, extension)| extension.into()).collect())
173    }
174}
175
176impl fmt::Display for Extensions {
177    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
178        writeln!(f, "{}", Table::new(self.0.iter().cloned()))
179    }
180}
181
182pub struct ExtensionsTableOptions;
183
184impl TableOptions for ExtensionsTableOptions {
185    fn options(table: &mut Table) -> &mut Table {
186        table.with(Style::extended())
187    }
188}