use std::sync::Arc;
use serde_json::Value;
use crate::tui::model::{FieldKind, FieldSchema};
use crate::tui::state::error::FieldCoercionError;
use crate::tui::state::field::convert::{
integer_value, number_value, string_value, value_to_string,
};
use super::helpers::handle_text_edit;
use super::{ComponentKind, FieldComponent, palette::ComponentPalette};
#[derive(Debug, Clone)]
pub struct TextComponent {
buffer: String,
palette: Arc<ComponentPalette>,
}
impl TextComponent {
pub fn new(schema: &FieldSchema, palette: Arc<ComponentPalette>) -> Self {
let buffer = schema
.default
.as_ref()
.map(value_to_string)
.unwrap_or_default();
Self { buffer, palette }
}
}
impl FieldComponent for TextComponent {
fn kind(&self) -> ComponentKind {
ComponentKind::TextInput
}
fn display_value(&self, _schema: &FieldSchema) -> String {
self.buffer.clone()
}
fn handle_key(&mut self, schema: &FieldSchema, key: &crossterm::event::KeyEvent) -> bool {
handle_text_edit(&mut self.buffer, schema, key, &self.palette)
}
fn seed_value(&mut self, _schema: &FieldSchema, value: &Value) {
match value {
Value::String(text) => self.buffer = text.clone(),
Value::Number(num) => self.buffer = num.to_string(),
other => self.buffer = value_to_string(other),
}
}
fn current_value(&self, schema: &FieldSchema) -> Result<Option<Value>, FieldCoercionError> {
match schema.kind {
FieldKind::String => string_value(&self.buffer, schema),
FieldKind::Integer => integer_value(&self.buffer, schema),
FieldKind::Number => number_value(&self.buffer, schema),
FieldKind::Json => string_value(&self.buffer, schema),
_ => Ok(None),
}
}
}