use napi_derive::napi;
use serde::{Deserialize, Serialize};
#[napi(object)]
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct StyleNapi {
pub fg: Option<String>,
pub bg: Option<String>,
pub bold: Option<bool>,
pub dim: Option<bool>,
pub italic: Option<bool>,
pub underline: Option<bool>,
pub inverse: Option<bool>,
pub blink: Option<bool>,
pub hidden: Option<bool>,
pub strikethrough: Option<bool>,
}
#[napi(object)]
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct FlexStyleNapi {
pub display: Option<String>,
pub position: Option<String>,
pub top: Option<String>,
pub right: Option<String>,
pub bottom: Option<String>,
pub left: Option<String>,
pub overflow: Option<String>,
#[napi(js_name = "overflowX")]
pub overflow_x: Option<String>,
#[napi(js_name = "overflowY")]
pub overflow_y: Option<String>,
#[napi(js_name = "flexDirection")]
pub flex_direction: Option<String>,
#[napi(js_name = "flexWrap")]
pub flex_wrap: Option<String>,
#[napi(js_name = "justifyContent")]
pub justify_content: Option<String>,
#[napi(js_name = "alignItems")]
pub align_items: Option<String>,
#[napi(js_name = "alignSelf")]
pub align_self: Option<String>,
#[napi(js_name = "alignContent")]
pub align_content: Option<String>,
#[napi(js_name = "flexGrow")]
pub flex_grow: Option<f64>,
#[napi(js_name = "flexShrink")]
pub flex_shrink: Option<f64>,
#[napi(js_name = "flexBasis")]
pub flex_basis: Option<String>,
pub width: Option<String>,
pub height: Option<String>,
#[napi(js_name = "minWidth")]
pub min_width: Option<String>,
#[napi(js_name = "minHeight")]
pub min_height: Option<String>,
#[napi(js_name = "maxWidth")]
pub max_width: Option<String>,
#[napi(js_name = "maxHeight")]
pub max_height: Option<String>,
#[napi(js_name = "aspectRatio")]
pub aspect_ratio: Option<f64>,
pub padding: Option<f64>,
#[napi(js_name = "paddingTop")]
pub padding_top: Option<f64>,
#[napi(js_name = "paddingRight")]
pub padding_right: Option<f64>,
#[napi(js_name = "paddingBottom")]
pub padding_bottom: Option<f64>,
#[napi(js_name = "paddingLeft")]
pub padding_left: Option<f64>,
pub margin: Option<f64>,
#[napi(js_name = "marginTop")]
pub margin_top: Option<f64>,
#[napi(js_name = "marginRight")]
pub margin_right: Option<f64>,
#[napi(js_name = "marginBottom")]
pub margin_bottom: Option<f64>,
#[napi(js_name = "marginLeft")]
pub margin_left: Option<f64>,
pub gap: Option<f64>,
#[napi(js_name = "columnGap")]
pub column_gap: Option<f64>,
#[napi(js_name = "rowGap")]
pub row_gap: Option<f64>,
}
#[napi(object)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RenderNodeNapi {
pub id: i64,
#[napi(js_name = "nodeType")]
pub node_type: String,
pub text: Option<String>,
pub wrap: Option<bool>,
#[napi(js_name = "wrapMode")]
pub wrap_mode: Option<String>,
pub value: Option<String>,
pub placeholder: Option<String>,
pub focused: Option<bool>,
pub cursor: Option<i64>,
pub mask: Option<bool>,
#[napi(js_name = "maskChar")]
pub mask_char: Option<String>,
pub style: Option<FlexStyleNapi>,
pub appearance: Option<StyleNapi>,
pub border: Option<String>,
pub children: Option<Vec<i64>>,
}
#[napi(object)]
#[derive(Debug, Clone, Default)]
pub struct LayoutResultNapi {
pub id: i64,
pub x: i32,
pub y: i32,
pub width: i32,
pub height: i32,
}
#[napi(object)]
#[derive(Debug, Clone)]
pub struct InputEventNapi {
#[napi(ts_type = "\"key\" | \"mouse\" | \"resize\" | \"focus\" | \"paste\" | (string & {})")]
pub event_type: String,
pub key: Option<String>,
pub char: Option<String>,
#[napi(js_name = "keyEventType")]
pub key_event_type: Option<String>,
pub modifiers: Option<ModifiersNapi>,
pub button: Option<String>,
pub x: Option<i32>,
pub y: Option<i32>,
pub width: Option<i32>,
pub height: Option<i32>,
pub text: Option<String>,
pub cursor: Option<i32>,
}
#[napi(object)]
#[derive(Debug, Clone, Default)]
pub struct ModifiersNapi {
pub ctrl: bool,
pub alt: bool,
pub shift: bool,
pub meta: bool,
#[napi(js_name = "super")]
pub super_key: bool,
pub hyper: bool,
#[napi(js_name = "capsLock")]
pub caps_lock: bool,
#[napi(js_name = "numLock")]
pub num_lock: bool,
}
#[napi(object)]
#[derive(Debug, Clone, Default)]
pub struct ImeStateNapi {
pub active: bool,
pub mode: String,
pub composing: bool,
pub preedit: Option<String>,
pub preedit_cursor: Option<i32>,
pub candidates: Option<Vec<String>>,
pub selected: Option<i32>,
}
#[napi(object)]
#[derive(Debug, Clone, Default)]
pub struct TerminalInfoNapi {
pub width: i32,
pub height: i32,
pub colors: bool,
pub true_color: bool,
}
#[napi(object)]
#[derive(Debug, Clone, Default)]
pub struct TerminalOptionsNapi {
#[napi(js_name = "rawMode")]
pub raw_mode: Option<bool>,
#[napi(js_name = "alternateScreen")]
pub alternate_screen: Option<bool>,
pub mouse: Option<bool>,
#[napi(js_name = "bracketedPaste")]
pub bracketed_paste: Option<bool>,
#[napi(js_name = "hideCursor")]
pub hide_cursor: Option<bool>,
}
fn modifiers_from_key(key: &crate::input::KeyEvent) -> ModifiersNapi {
ModifiersNapi {
ctrl: key.ctrl(),
alt: key.alt(),
shift: key.shift(),
meta: key.modifiers.meta,
super_key: key.modifiers.super_key,
hyper: key.modifiers.hyper,
caps_lock: false,
num_lock: false,
}
}
impl From<crate::input::Event> for InputEventNapi {
fn from(event: crate::input::Event) -> Self {
use crate::input::Event;
match event {
Event::Key(key) => {
let key_str = match key.key {
crate::input::Key::Char(c) => {
return InputEventNapi {
event_type: "key".to_string(),
key: None,
char: Some(c.to_string()),
key_event_type: Some(key.kind.as_str().to_string()),
modifiers: Some(modifiers_from_key(&key)),
button: None,
x: None,
y: None,
width: None,
height: None,
text: None,
cursor: None,
};
}
crate::input::Key::Enter => "enter",
crate::input::Key::Backspace => "backspace",
crate::input::Key::Delete => "delete",
crate::input::Key::Left => "left",
crate::input::Key::Right => "right",
crate::input::Key::Up => "up",
crate::input::Key::Down => "down",
crate::input::Key::Home => "home",
crate::input::Key::End => "end",
crate::input::Key::PageUp => "pageup",
crate::input::Key::PageDown => "pagedown",
crate::input::Key::Tab => "tab",
crate::input::Key::BackTab => "backtab",
crate::input::Key::Esc => "escape",
crate::input::Key::F(n) => {
#[allow(clippy::disallowed_macros)]
return InputEventNapi {
event_type: "key".to_string(),
key: Some(format!("f{}", n)),
char: None,
key_event_type: Some(key.kind.as_str().to_string()),
modifiers: Some(modifiers_from_key(&key)),
button: None,
x: None,
y: None,
width: None,
height: None,
text: None,
cursor: None,
};
}
_ => "unknown",
};
InputEventNapi {
event_type: "key".to_string(),
key: Some(key_str.to_string()),
char: None,
key_event_type: Some(key.kind.as_str().to_string()),
modifiers: Some(modifiers_from_key(&key)),
button: None,
x: None,
y: None,
width: None,
height: None,
text: None,
cursor: None,
}
}
Event::Mouse(mouse) => {
let button = match mouse.kind {
crate::input::MouseEventKind::Down(b)
| crate::input::MouseEventKind::Up(b)
| crate::input::MouseEventKind::Drag(b) => match b {
crate::input::MouseButton::Left => Some("left".to_string()),
crate::input::MouseButton::Right => Some("right".to_string()),
crate::input::MouseButton::Middle => Some("middle".to_string()),
},
_ => None,
};
InputEventNapi {
event_type: "mouse".to_string(),
key: None,
char: None,
key_event_type: None,
modifiers: None,
button,
x: Some(mouse.column as i32),
y: Some(mouse.row as i32),
width: None,
height: None,
text: None,
cursor: None,
}
}
Event::Resize(w, h) => InputEventNapi {
event_type: "resize".to_string(),
key: None,
char: None,
key_event_type: None,
modifiers: None,
button: None,
x: None,
y: None,
width: Some(w as i32),
height: Some(h as i32),
text: None,
cursor: None,
},
Event::FocusGained => InputEventNapi {
event_type: "focus".to_string(),
key: Some("gained".to_string()),
char: None,
key_event_type: None,
modifiers: None,
button: None,
x: None,
y: None,
width: None,
height: None,
text: None,
cursor: None,
},
Event::FocusLost => InputEventNapi {
event_type: "focus".to_string(),
key: Some("lost".to_string()),
char: None,
key_event_type: None,
modifiers: None,
button: None,
x: None,
y: None,
width: None,
height: None,
text: None,
cursor: None,
},
Event::Paste(text) => InputEventNapi {
event_type: "paste".to_string(),
key: None,
char: None,
key_event_type: None,
modifiers: None,
button: None,
x: None,
y: None,
width: None,
height: None,
text: Some(text.into()),
cursor: None,
},
}
}
}