1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 13:52:55 +03:00

Enable serializing various Line and Cell related structs

This commit is contained in:
Wez Furlong 2019-03-14 07:58:48 -07:00
parent 86ed003428
commit 7cdd1876d1
16 changed files with 138 additions and 22 deletions

View File

@ -12,7 +12,7 @@ failure_derive = "~0.1"
gl = "~0.11" gl = "~0.11"
libc = "~0.2" libc = "~0.2"
palette = "~0.4" palette = "~0.4"
serde = "~1.0" serde = {version="~1.0", features = ["rc"]}
serde_derive = "~1.0" serde_derive = "~1.0"
toml = "~0.4" toml = "~0.4"
unicode-width = "~0.1" unicode-width = "~0.1"

View File

@ -5,6 +5,7 @@ use crate::frontend::FrontEndSelection;
use crate::{get_shell, Command}; use crate::{get_shell, Command};
use failure::{err_msg, Error}; use failure::{err_msg, Error};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde_derive::*;
use std; use std;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs; use std::fs;

View File

@ -1,4 +1,5 @@
use failure::Error; use failure::Error;
use serde_derive::*;
mod ftfont; mod ftfont;
#[cfg(unix)] #[cfg(unix)]
mod hbwrap; mod hbwrap;

View File

@ -4,6 +4,7 @@ use crate::mux::tab::Tab;
use crate::mux::Mux; use crate::mux::Mux;
use failure::Error; use failure::Error;
use promise::Executor; use promise::Executor;
use serde_derive::*;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;

View File

@ -3,8 +3,6 @@ extern crate failure;
#[macro_use] #[macro_use]
extern crate failure_derive; extern crate failure_derive;
#[macro_use] #[macro_use]
extern crate serde_derive;
#[macro_use]
pub mod log; pub mod log;
use failure::Error; use failure::Error;
use std::ffi::OsString; use std::ffi::OsString;

View File

@ -13,7 +13,11 @@
use crate::mux::tab::TabId; use crate::mux::tab::TabId;
use bincode; use bincode;
use failure::Error; use failure::Error;
use serde_derive::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
use term::{CursorPosition, Line};
use termwiz::hyperlink::Hyperlink;
use varu64; use varu64;
fn encode_raw<W: std::io::Write>( fn encode_raw<W: std::io::Write>(
@ -148,6 +152,32 @@ pub struct ListTabsResponse {
pub tabs: HashMap<TabId, String>, pub tabs: HashMap<TabId, String>,
} }
/// This is a transitional request to get some basic
/// remoting working. The ideal is to produce Change
/// objects instead of the coarse response data in
/// GetCoarseTabRenderableDataResponse
#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct GetCoarseTabRenderableData {
pub tab_id: TabId,
}
#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct DirtyLine {
pub line_idx: usize,
pub line: Line,
pub selection_col_from: usize,
pub selection_col_to: usize,
}
#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct GetCoarseTabRenderableDataResponse {
pub cursor_position: CursorPosition,
pub physical_rows: usize,
pub physical_cols: usize,
pub current_highlight: Option<Rc<Hyperlink>>,
pub dirty_lines: Vec<DirtyLine>,
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;

View File

@ -11,6 +11,8 @@ image = "~0.19"
ordered-float = "~0.5" ordered-float = "~0.5"
unicode-segmentation = "~1.2" unicode-segmentation = "~1.2"
unicode-width = "~0.1" unicode-width = "~0.1"
serde = {version="~1.0", features = ["rc"]}
serde_derive = "~1.0"
[dependencies.termwiz] [dependencies.termwiz]
path = "../termwiz" path = "../termwiz"

View File

@ -3,6 +3,7 @@
extern crate bitflags; extern crate bitflags;
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
use serde_derive::*;
use failure::Error; use failure::Error;
use std::ops::{Deref, DerefMut, Range}; use std::ops::{Deref, DerefMut, Range};
@ -85,7 +86,7 @@ pub enum Position {
/// Describes the location of the cursor in the visible portion /// Describes the location of the cursor in the visible portion
/// of the screen. /// of the screen.
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct CursorPosition { pub struct CursorPosition {
pub x: usize, pub x: usize,
pub y: VisibleRowIndex, pub y: VisibleRowIndex,

View File

@ -20,7 +20,7 @@ ordered-float = "~0.5"
palette = "~0.4" palette = "~0.4"
regex = "~0.2" regex = "~0.2"
semver = "0.9" semver = "0.9"
serde = "~1.0" serde = {version="~1.0", features = ["rc"]}
serde_derive = "~1.0" serde_derive = "~1.0"
smallvec = "~0.6" smallvec = "~0.6"
terminfo = "~0.6" terminfo = "~0.6"
@ -28,6 +28,9 @@ unicode-segmentation = "~1.2"
unicode-width = "~0.1" unicode-width = "~0.1"
vte = "~0.3" vte = "~0.3"
[dev-dependencies]
bincode = "1.1"
[dependencies.num-derive] [dependencies.num-derive]
features = ["full-syntax"] features = ["full-syntax"]
version = "~0.2" version = "~0.2"

View File

@ -2,6 +2,7 @@
use crate::color::ColorAttribute; use crate::color::ColorAttribute;
pub use crate::escape::osc::Hyperlink; pub use crate::escape::osc::Hyperlink;
use crate::image::ImageCell; use crate::image::ImageCell;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use smallvec::SmallVec; use smallvec::SmallVec;
use std; use std;
use std::mem; use std::mem;
@ -13,7 +14,7 @@ use unicode_width::UnicodeWidthStr;
/// to reduce per-cell overhead. /// to reduce per-cell overhead.
/// The setter methods return a mutable self reference so that they can /// The setter methods return a mutable self reference so that they can
/// be chained together. /// be chained together.
#[derive(Debug, Default, Clone, Eq, PartialEq)] #[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct CellAttributes { pub struct CellAttributes {
attributes: u16, attributes: u16,
/// The foreground color /// The foreground color
@ -84,7 +85,7 @@ macro_rules! bitfield {
/// implement `Intensity::Bold` by either using a bold font or by simply /// implement `Intensity::Bold` by either using a bold font or by simply
/// using an alternative color. Some terminals implement `Intensity::Half` /// using an alternative color. Some terminals implement `Intensity::Half`
/// as a dimmer color variant. /// as a dimmer color variant.
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[repr(u16)] #[repr(u16)]
pub enum Intensity { pub enum Intensity {
Normal = 0, Normal = 0,
@ -93,7 +94,7 @@ pub enum Intensity {
} }
/// Specify just how underlined you want your `Cell` to be /// Specify just how underlined you want your `Cell` to be
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[repr(u16)] #[repr(u16)]
pub enum Underline { pub enum Underline {
/// The cell is not underlined /// The cell is not underlined
@ -114,7 +115,7 @@ impl Into<bool> for Underline {
} }
/// Specify whether you want to slowly or rapidly annoy your users /// Specify whether you want to slowly or rapidly annoy your users
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[repr(u16)] #[repr(u16)]
pub enum Blink { pub enum Blink {
None = 0, None = 0,
@ -181,9 +182,31 @@ impl CellAttributes {
} }
} }
fn deserialize_smallvec<'de, D>(deserializer: D) -> Result<SmallVec<[u8; 4]>, D::Error>
where
D: Deserializer<'de>,
{
let text = String::deserialize(deserializer)?;
Ok(SmallVec::from_slice(text.as_bytes()))
}
fn serialize_smallvec<S>(value: &SmallVec<[u8; 4]>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// unsafety: this is safe because the Cell constructor guarantees
// that the storage is valid utf8
let s = unsafe { std::str::from_utf8_unchecked(value) };
s.serialize(serializer)
}
/// Models the contents of a cell on the terminal display /// Models the contents of a cell on the terminal display
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct Cell { pub struct Cell {
#[serde(
deserialize_with = "deserialize_smallvec",
serialize_with = "serialize_smallvec"
)]
text: SmallVec<[u8; 4]>, text: SmallVec<[u8; 4]>,
attrs: CellAttributes, attrs: CellAttributes,
} }
@ -275,7 +298,7 @@ impl Cell {
/// Models a change in the attributes of a cell in a stream of changes. /// Models a change in the attributes of a cell in a stream of changes.
/// Each variant specifies one of the possible attributes; the corresponding /// Each variant specifies one of the possible attributes; the corresponding
/// value holds the new value to be used for that attribute. /// value holds the new value to be used for that attribute.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum AttributeChange { pub enum AttributeChange {
Intensity(Intensity), Intensity(Intensity),
Underline(Underline), Underline(Underline),

View File

@ -4,7 +4,7 @@
use palette; use palette;
use palette::{LinSrgba, Srgb, Srgba}; use palette::{LinSrgba, Srgb, Srgba};
use serde::{self, Deserialize, Deserializer}; use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result; use std::result::Result;
#[derive(Debug, Clone, Copy, FromPrimitive)] #[derive(Debug, Clone, Copy, FromPrimitive)]
@ -97,6 +97,11 @@ impl RgbColor {
}) })
} }
/// Returns a string of the form `#RRGGBB`
pub fn to_rgb_string(&self) -> String {
format!("#{:02x}{:02x}{:02x}", self.red, self.green, self.blue)
}
/// Construct a color from a string of the form `#RRGGBB` where /// Construct a color from a string of the form `#RRGGBB` where
/// R, G and B are all hex digits. /// R, G and B are all hex digits.
pub fn from_rgb_str(s: &str) -> Option<RgbColor> { pub fn from_rgb_str(s: &str) -> Option<RgbColor> {
@ -123,6 +128,23 @@ impl RgbColor {
} }
} }
/// This is mildly unfortunate: in order to round trip RgbColor with serde
/// we need to provide a Serialize impl equivalent to the Deserialize impl
/// below. We use the impl below to allow more flexible specification of
/// color strings in the config file. A side effect of doing it this way
/// is that we have to serialize RgbColor as a 7-byte string when we could
/// otherwise serialize it as a 3-byte array. There's probably a way
/// to make this work more efficiently, but for now this will do.
impl Serialize for RgbColor {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = self.to_rgb_string();
s.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for RgbColor { impl<'de> Deserialize<'de> for RgbColor {
fn deserialize<D>(deserializer: D) -> Result<RgbColor, D::Error> fn deserialize<D>(deserializer: D) -> Result<RgbColor, D::Error>
where where
@ -173,7 +195,7 @@ impl From<RgbColor> for ColorSpec {
/// type used in the `CellAttributes` struct and can specify an optional /// type used in the `CellAttributes` struct and can specify an optional
/// TrueColor value, allowing a fallback to a more traditional palette /// TrueColor value, allowing a fallback to a more traditional palette
/// index if TrueColor is not available. /// index if TrueColor is not available.
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
pub enum ColorAttribute { pub enum ColorAttribute {
/// Use RgbColor when supported, falling back to the specified PaletteIndex. /// Use RgbColor when supported, falling back to the specified PaletteIndex.
TrueColorWithPaletteFallback(RgbColor, PaletteIndex), TrueColorWithPaletteFallback(RgbColor, PaletteIndex),
@ -217,4 +239,11 @@ mod tests {
assert_eq!(dark_green.green, 0x64); assert_eq!(dark_green.green, 0x64);
assert_eq!(dark_green.blue, 0); assert_eq!(dark_green.blue, 0);
} }
#[test]
fn roundtrip_rgbcolor() {
let data = bincode::serialize(&RgbColor::from_named("DarkGreen").unwrap()).unwrap();
eprintln!("serialized as {:?}", data);
let decoded: RgbColor = bincode::deserialize(&data).unwrap();
}
} }

View File

@ -7,12 +7,13 @@
use failure::{err_msg, Error}; use failure::{err_msg, Error};
use regex::{Captures, Regex}; use regex::{Captures, Regex};
use serde::{self, Deserialize, Deserializer}; use serde::{self, Deserialize, Deserializer};
use serde_derive::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::{Display, Error as FmtError, Formatter}; use std::fmt::{Display, Error as FmtError, Formatter};
use std::ops::Range; use std::ops::Range;
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Hyperlink { pub struct Hyperlink {
params: HashMap<String, String>, params: HashMap<String, String>,
uri: String, uri: String,

View File

@ -12,11 +12,36 @@
// z-order. // z-order.
use ordered_float::NotNaN; use ordered_float::NotNaN;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_derive::*;
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug, Clone, PartialEq, Eq)] fn deserialize_notnan<'de, D>(deserializer: D) -> Result<NotNaN<f32>, D::Error>
where
D: Deserializer<'de>,
{
let value = f32::deserialize(deserializer)?;
NotNaN::new(value).map_err(|e| serde::de::Error::custom(format!("{:?}", e)))
}
fn serialize_notnan<S>(value: &NotNaN<f32>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
value.into_inner().serialize(serializer)
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TextureCoordinate { pub struct TextureCoordinate {
#[serde(
deserialize_with = "deserialize_notnan",
serialize_with = "serialize_notnan"
)]
pub x: NotNaN<f32>, pub x: NotNaN<f32>,
#[serde(
deserialize_with = "deserialize_notnan",
serialize_with = "serialize_notnan"
)]
pub y: NotNaN<f32>, pub y: NotNaN<f32>,
} }
@ -37,7 +62,7 @@ impl TextureCoordinate {
/// carve up the image and track each slice of it. Each cell needs to know /// carve up the image and track each slice of it. Each cell needs to know
/// its "texture coordinates" within that image so that we can render the /// its "texture coordinates" within that image so that we can render the
/// right slice. /// right slice.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImageCell { pub struct ImageCell {
/// Texture coordinate for the top left of this cell. /// Texture coordinate for the top left of this cell.
/// (0,0) is the top left of the ImageData. (1, 1) is /// (0,0) is the top left of the ImageData. (1, 1) is
@ -65,7 +90,7 @@ impl ImageCell {
static IMAGE_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT; static IMAGE_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImageData { pub struct ImageData {
id: usize, id: usize,
/// The image data bytes. Data is the native image file format /// The image data bytes. Data is the native image file format

View File

@ -7,7 +7,7 @@ use std::rc::Rc;
/// `Change` describes an update operation to be applied to a `Surface`. /// `Change` describes an update operation to be applied to a `Surface`.
/// Changes to the active attributes (color, style), moving the cursor /// Changes to the active attributes (color, style), moving the cursor
/// and outputting text are examples of some of the values. /// and outputting text are examples of some of the values.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum Change { pub enum Change {
/// Change a single attribute /// Change a single attribute
Attribute(AttributeChange), Attribute(AttributeChange),
@ -90,7 +90,7 @@ impl From<AttributeChange> for Change {
/// A 4x3 cell image would set `width=3`, `height=3`, `top_left=(0,0)`, `bottom_right=(1,1)`. /// A 4x3 cell image would set `width=3`, `height=3`, `top_left=(0,0)`, `bottom_right=(1,1)`.
/// The top left cell from that image, if it were to be included in a diff, /// The top left cell from that image, if it were to be included in a diff,
/// would be recorded as `width=1`, `height=1`, `top_left=(0,0)`, `bottom_right=(1/4,1/3)`. /// would be recorded as `width=1`, `height=1`, `top_left=(0,0)`, `bottom_right=(1/4,1/3)`.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Image { pub struct Image {
/// measured in cells /// measured in cells
pub width: usize, pub width: usize,

View File

@ -8,6 +8,7 @@ use std::rc::Rc;
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
bitflags! { bitflags! {
#[derive(Serialize, Deserialize)]
struct LineBits : u8 { struct LineBits : u8 {
const NONE = 0; const NONE = 0;
/// The contents of the Line have changed and cached or /// The contents of the Line have changed and cached or
@ -22,7 +23,7 @@ bitflags! {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Line { pub struct Line {
bits: LineBits, bits: LineBits,
cells: Vec<Cell>, cells: Vec<Cell>,

View File

@ -17,7 +17,7 @@ pub use self::line::Line;
/// Relative(0) is the current position in the line or /// Relative(0) is the current position in the line or
/// column and EndRelative(0) is the end position in the /// column and EndRelative(0) is the end position in the
/// line or column. /// line or column.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum Position { pub enum Position {
NoChange, NoChange,
/// Negative values move up, positive values down /// Negative values move up, positive values down
@ -28,7 +28,7 @@ pub enum Position {
EndRelative(usize), EndRelative(usize),
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CursorShape { pub enum CursorShape {
Hidden, Hidden,
Default, Default,