use std::collections::BTreeMap;
use serde::{Serialize, Serializer, ser::SerializeMap};
use serde_json::Value;
use super::{
icon::Icon,
types::{ChoiceStyle, ColumnFormat, ItemStatus, Text, TextAlign, Tone, Truncate},
};
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct KvItem {
pub k: Text,
pub v: Text,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct Column {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub head: Option<Text>,
#[serde(skip_serializing_if = "Option::is_none")]
pub align: Option<TextAlign>,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncate: Option<Truncate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub grow: Option<f64>,
}
impl Column {
pub fn new(id: impl Into<String>, head: impl Into<Text>) -> Self {
Self { id: id.into(), head: Some(head.into()), ..Self::default() }
}
pub fn align(mut self, align: impl Into<TextAlign>) -> Self {
self.align = Some(align.into());
self
}
pub const fn grow(mut self, grow: f64) -> Self {
self.grow = Some(grow);
self
}
pub const fn priority(mut self, priority: f64) -> Self {
self.priority = Some(priority);
self
}
pub fn truncate(mut self, truncate: impl Into<Truncate>) -> Self {
self.truncate = Some(truncate.into());
self
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct Part {
pub value: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hatch: Option<bool>,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize)]
pub struct Thresholds {
#[serde(skip_serializing_if = "Option::is_none")]
pub warn: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bad: Option<f64>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct MeterCell {
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<f64>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub parts: Vec<Part>,
#[serde(skip_serializing_if = "Option::is_none")]
pub thresholds: Option<Thresholds>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tone: Option<Tone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum Cell {
Text(Text),
Meter(MeterCell),
}
impl Serialize for Cell {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
Self::Text(t) => t.serialize(s),
Self::Meter(m) => {
let mut map = s.serialize_map(Some(1))?;
map.serialize_entry("meter", m)?;
map.end()
},
}
}
}
impl<T: Into<Text>> From<T> for Cell {
fn from(t: T) -> Self {
Self::Text(t.into())
}
}
impl From<MeterCell> for Cell {
fn from(m: MeterCell) -> Self {
Self::Meter(m)
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct TableRow {
pub id: String,
pub cells: BTreeMap<String, Cell>,
}
impl TableRow {
pub fn new(id: impl Into<String>) -> Self {
Self { id: id.into(), cells: BTreeMap::new() }
}
pub fn cell(mut self, col: impl Into<String>, cell: impl Into<Cell>) -> Self {
self.cells.insert(col.into(), cell.into());
self
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct TreeItem {
pub id: String,
pub label: Text,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
#[serde(skip_serializing_if = "Option::is_none")]
pub open: Option<bool>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub children: Vec<Self>,
}
impl TreeItem {
pub fn new(id: impl Into<String>, label: impl Into<Text>) -> Self {
Self { id: id.into(), label: label.into(), ..Self::default() }
}
pub fn child(mut self, item: Self) -> Self {
self.children.push(item);
self
}
pub const fn open(mut self, open: bool) -> Self {
self.open = Some(open);
self
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Tab {
pub id: String,
pub label: Text,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct CodeMark {
pub line: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub tone: Option<Tone>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub ranges: Vec<[u64; 2]>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Hunk {
#[serde(skip_serializing_if = "Option::is_none")]
pub old_start: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub new_start: Option<u64>,
pub lines: Vec<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Decor {
pub from: usize,
pub to: usize,
pub s: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub fx: Option<super::types::Fx>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct ShimmerPalette {
#[serde(skip_serializing_if = "Option::is_none")]
pub low: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub high: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct MeterMark {
pub at: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub tone: Option<Tone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct Point {
pub value: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct ChartCol {
pub at: u32,
pub label: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Anchor {
Center,
Top,
Bottom,
Node {
id: String,
above: bool,
},
Caret(String),
}
impl Serialize for Anchor {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap as _;
match self {
Self::Center => s.serialize_str("center"),
Self::Top => s.serialize_str("top"),
Self::Bottom => s.serialize_str("bottom"),
Self::Node { id, above } => {
let mut m = s.serialize_map(Some(2))?;
m.serialize_entry("node", id)?;
m.serialize_entry("side", if *above { "above" } else { "below" })?;
m.end()
},
Self::Caret(id) => {
let mut m = s.serialize_map(Some(1))?;
m.serialize_entry("caret", id)?;
m.end()
},
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct BadgeSpec {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub tone: Option<Tone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct ToolButton {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub keys: Vec<String>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ToolPreview {
Lines(u32),
Tail(u32),
}
impl Serialize for ToolPreview {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap as _;
let mut m = s.serialize_map(Some(1))?;
match *self {
Self::Lines(n) => m.serialize_entry("lines", &n)?,
Self::Tail(n) => m.serialize_entry("tail", &n)?,
}
m.end()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Preview {
Auto,
Lines(u32),
}
impl Serialize for Preview {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap as _;
match *self {
Self::Auto => s.serialize_str("auto"),
Self::Lines(n) => {
let mut m = s.serialize_map(Some(1))?;
m.serialize_entry("lines", &n)?;
m.end()
},
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AgentStats {
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub requests: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub done: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context_label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tokens: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cost: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub age: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub took: Option<u64>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct AgentTool {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub intent: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub age: Option<i64>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Retry {
#[serde(skip_serializing_if = "Option::is_none")]
pub attempt: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delay: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub age: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct ChecklistItem {
pub id: String,
pub text: Text,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<ItemStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub note: Option<Text>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Phase {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<Text>,
pub items: Vec<ChecklistItem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collapsed: Option<bool>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct PickerItem {
pub id: String,
pub label: Text,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<Text>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mark: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dot: Option<Tone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mono: Option<bool>,
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub facts: BTreeMap<String, Value>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub badges: Vec<BadgeSpec>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub chips: Vec<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tone: Option<Tone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<Value>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub hits: Vec<[usize; 2]>,
#[serde(skip_serializing_if = "Option::is_none")]
pub node: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub depth: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub open: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
}
impl PickerItem {
pub fn new(id: impl Into<String>, label: impl Into<Text>) -> Self {
Self { id: id.into(), label: label.into(), ..Self::default() }
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum OrderEntry {
Item(String),
Group {
group: String,
label: String,
count: Option<u64>,
},
}
impl Serialize for OrderEntry {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap as _;
match self {
Self::Item(id) => s.serialize_str(id),
Self::Group { group, label, count } => {
let mut m = s.serialize_map(None)?;
m.serialize_entry("group", group)?;
m.serialize_entry("label", label)?;
if let Some(count) = count {
m.serialize_entry("count", count)?;
}
m.end()
},
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct PickerColumn {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub head: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<ColumnFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min: Option<u32>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Confirm {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub act: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Scope {
pub id: String,
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mark: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dot: Option<Tone>,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<Value>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct PickerTab {
pub id: String,
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<u64>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct StripItem {
pub id: String,
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub on: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dot: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Strip {
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
pub items: Vec<StripItem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub selected: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct PickerAction {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub keys: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub primary: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub danger: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub on: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<Value>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct PrefsPage {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub changed: Option<u32>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
pub struct PrefsSection {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<String>,
pub rows: Vec<PrefsRow>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PrefsRow {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub warning: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub changed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub control: Option<Control>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct ChoiceOption {
pub value: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(tag = "k", rename_all = "lowercase")]
pub enum Control {
Switch {
on: bool,
},
Choice {
value: String,
options: Vec<ChoiceOption>,
#[serde(skip_serializing_if = "Option::is_none")]
style: Option<ChoiceStyle>,
#[serde(skip_serializing_if = "Option::is_none")]
mono: Option<bool>,
},
Number {
value: f64,
#[serde(skip_serializing_if = "Option::is_none")]
min: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
max: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
step: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
unit: Option<String>,
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
labels: BTreeMap<String, String>,
},
Text {
value: String,
#[serde(skip_serializing_if = "Option::is_none")]
placeholder: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
secret: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
mono: Option<bool>,
},
Keys {
keys: Vec<Vec<String>>,
},
Multi {
values: Vec<String>,
options: Vec<ChoiceOption>,
#[serde(skip_serializing_if = "Option::is_none")]
ordered: Option<bool>,
},
Action {
#[serde(skip_serializing_if = "Option::is_none")]
act: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
label: Option<String>,
},
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub struct Editing {
pub row: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub option: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub draft: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<usize>,
}