feat: implement new data display component
This commit is contained in:
1 parent
07c1679e1a
commit
eae8d2a26a
6 files changed
+506
-355
No files matched your search
+170
-15
@@ -1,13 +1,35 @@
|
||||
use std::collections::HashMap;
|
||||
use indexmap::IndexMap;
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone)]
|
||||
pub enum SchemaType {
|
||||
/// Indicates a `ValueType::String` value.
|
||||
#[default]
|
||||
String,
|
||||
/// Indicates a `ValueType::Number` value.
|
||||
Number,
|
||||
List,
|
||||
Map
|
||||
/// Indicates a `ValueType::List` containing only strings or numbers.
|
||||
PrimitiveList,
|
||||
/// Indicates a `ValueType::List` containing only maps.
|
||||
MapList,
|
||||
/// Indicates a `ValueType::Map`.
|
||||
Map,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone)]
|
||||
pub enum SchemaContainerStyle {
|
||||
#[default]
|
||||
Header,
|
||||
Capsule,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone)]
|
||||
pub enum SchemaHeaderStyle {
|
||||
#[default]
|
||||
None,
|
||||
MainHeader,
|
||||
SubsectionHeader,
|
||||
Bold,
|
||||
}
|
||||
|
||||
/// # Schema Node
|
||||
@@ -55,12 +77,16 @@ pub enum SchemaType {
|
||||
/// This schema does not currently support display of a single nested member, like a single map
|
||||
/// within a list. This means that you will have to display any listed or mapped information as a
|
||||
/// list. Consider this when designing the data.
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone)]
|
||||
pub struct SchemaNode {
|
||||
/// The display style of the data. Refer to [`SchemaContainerStyle`] for more information.
|
||||
pub container_style: SchemaContainerStyle,
|
||||
/// The datatype of the data found using the `data_member` key.
|
||||
pub data_type: SchemaType,
|
||||
/// The header of this display.
|
||||
pub header: String,
|
||||
/// The style of the header's display.
|
||||
pub header_style: SchemaHeaderStyle,
|
||||
/// When used with a SchemaType::List, this determines the datatype and children for every entry
|
||||
/// in the list. Some examples include a list of maps, where we use the `item_template` to define
|
||||
/// the SchemaType::Map, and all its children. This is then mapped across all entries in the list,
|
||||
@@ -69,16 +95,28 @@ pub struct SchemaNode {
|
||||
/// When used with a SchemaType::Map, this determines what children from the map are displayed
|
||||
/// and how. It is ignored with all other SchemaType variants.
|
||||
pub children: IndexMap<String, SchemaNode>,
|
||||
/// The primary key for iteration over maps. Used when there is a list of maps.
|
||||
pub primary_key: Option<String>,
|
||||
}
|
||||
|
||||
impl SchemaNode {
|
||||
pub fn new(data_type: SchemaType) -> Self {
|
||||
SchemaNode {
|
||||
data_type,
|
||||
header: "".to_string(),
|
||||
item_template: None,
|
||||
children: IndexMap::new(),
|
||||
}
|
||||
/// Creates a new [`SchemaBuilder`].
|
||||
pub fn builder() -> SchemaBuilder {
|
||||
SchemaBuilder::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SchemaBuilder {
|
||||
container_style: SchemaContainerStyle,
|
||||
header: String,
|
||||
header_style: SchemaHeaderStyle,
|
||||
}
|
||||
|
||||
impl SchemaBuilder {
|
||||
pub fn container(mut self, style: SchemaContainerStyle) -> Self {
|
||||
self.container_style = style;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn header(mut self, header: impl Into<String>) -> Self {
|
||||
@@ -86,13 +124,130 @@ impl SchemaNode {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn child(mut self, data_member: impl Into<String>, node: SchemaNode) -> Self {
|
||||
self.children.insert(data_member.into(), node);
|
||||
pub fn header_style(mut self, header_style: SchemaHeaderStyle) -> Self {
|
||||
self.header_style = header_style;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn primitive_list(self) -> SchemaPrimitiveListBuilder {
|
||||
SchemaPrimitiveListBuilder::new(self)
|
||||
}
|
||||
|
||||
pub fn map_list(self) -> SchemaMapListBuilder {
|
||||
SchemaMapListBuilder::new(self)
|
||||
}
|
||||
|
||||
pub fn map(self) -> SchemaMapBuilder {
|
||||
SchemaMapBuilder::new(self)
|
||||
}
|
||||
|
||||
pub fn string(self) -> SchemaPrimitiveBuilder {
|
||||
SchemaPrimitiveBuilder::new(self, SchemaType::String)
|
||||
}
|
||||
|
||||
pub fn number(self) -> SchemaPrimitiveBuilder {
|
||||
SchemaPrimitiveBuilder::new(self, SchemaType::Number)
|
||||
}
|
||||
|
||||
fn into_node(self) -> SchemaNode {
|
||||
SchemaNode {
|
||||
container_style: self.container_style,
|
||||
header: self.header,
|
||||
header_style: self.header_style,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SchemaPrimitiveListBuilder {
|
||||
builder: SchemaBuilder,
|
||||
}
|
||||
|
||||
impl SchemaPrimitiveListBuilder {
|
||||
fn new(builder: SchemaBuilder) -> Self {
|
||||
Self { builder }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SchemaMapListBuilder {
|
||||
builder: SchemaBuilder,
|
||||
item_template: Option<Box<SchemaNode>>,
|
||||
primary_key: String,
|
||||
}
|
||||
|
||||
impl SchemaMapListBuilder {
|
||||
fn new(builder: SchemaBuilder) -> Self {
|
||||
Self {
|
||||
builder,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn item_template(mut self, node: SchemaNode) -> Self {
|
||||
self.item_template = Some(Box::new(node));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn primary_key(mut self, primary_key: impl Into<String>) -> Self {
|
||||
self.primary_key = primary_key.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> SchemaNode {
|
||||
SchemaNode {
|
||||
data_type: SchemaType::MapList,
|
||||
item_template: self.item_template,
|
||||
primary_key: Some(self.primary_key),
|
||||
..self.builder.into_node()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SchemaMapBuilder {
|
||||
builder: SchemaBuilder,
|
||||
children: IndexMap<String, SchemaNode>,
|
||||
}
|
||||
|
||||
impl SchemaMapBuilder {
|
||||
fn new(builder: SchemaBuilder) -> Self {
|
||||
Self {
|
||||
builder,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn child(mut self, data_member: impl Into<String>, node: SchemaNode) -> Self {
|
||||
self.children.insert(data_member.into(), node);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> SchemaNode {
|
||||
SchemaNode {
|
||||
data_type: SchemaType::Map,
|
||||
children: self.children,
|
||||
..self.builder.into_node()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SchemaPrimitiveBuilder {
|
||||
builder: SchemaBuilder,
|
||||
data_type: SchemaType,
|
||||
}
|
||||
|
||||
impl SchemaPrimitiveBuilder {
|
||||
fn new(builder: SchemaBuilder, data_type: SchemaType) -> Self {
|
||||
Self { data_type, builder }
|
||||
}
|
||||
|
||||
pub fn build(self) -> SchemaNode {
|
||||
SchemaNode {
|
||||
data_type: self.data_type,
|
||||
..self.builder.into_node()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user