Add serde support
This commit is contained in:
parent
7f245acf66
commit
b3339bc4c7
4 changed files with 237 additions and 35 deletions
40
src/lib.rs
40
src/lib.rs
|
@ -1,10 +1,18 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use cosmic_text::{Attrs, Buffer, Color, Family, FontSystem, Metrics, Shaping, Style, Weight};
|
||||
use cosmic_text::{
|
||||
Attrs, AttrsOwned, Buffer, Color, Family, FontSystem, Metrics, Shaping, Style, Weight,
|
||||
};
|
||||
use jotdown::{Container, Event, ListKind};
|
||||
|
||||
pub use jotdown;
|
||||
use range_map::RangeMap;
|
||||
use rangemap::RangeMap;
|
||||
#[cfg(feature = "serde")]
|
||||
mod serde_suck;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "serde")]
|
||||
pub use serde_suck::*;
|
||||
|
||||
pub struct JotdownBufferIter<'a, T: Iterator<Item = Event<'a>>> {
|
||||
djot: T,
|
||||
|
@ -18,13 +26,15 @@ struct JotdownIntoBuffer<'a, 'b, T: Iterator<Item = Event<'a>>> {
|
|||
indent: &'b mut Vec<Indent>,
|
||||
image_url: Option<Cow<'a, str>>,
|
||||
link_start: usize,
|
||||
urls: Vec<(range_map::Range<usize>, &'a str)>,
|
||||
urls: Vec<(std::ops::Range<usize>, Cow<'a, str>)>,
|
||||
location: usize,
|
||||
added: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Indent {
|
||||
#[cfg_attr(feature = "serde", serde(with = "ListKindOption"))]
|
||||
pub modifier: Option<ListKind>,
|
||||
pub indent: f32,
|
||||
}
|
||||
|
@ -115,7 +125,7 @@ impl<'a, 'b, T: Iterator<Item = Event<'a>>> Iterator for JotdownIntoBuffer<'a, '
|
|||
}
|
||||
Container::Link(Cow::Borrowed(url), _) => {
|
||||
self.urls
|
||||
.push((range_map::Range::new(self.link_start, self.location), url));
|
||||
.push((self.link_start..self.location, Cow::Borrowed(url)));
|
||||
self.attrs = self.attrs.color(Color::rgb(255, 255, 255));
|
||||
}
|
||||
_ => {}
|
||||
|
@ -130,12 +140,20 @@ impl<'a, 'b, T: Iterator<Item = Event<'a>>> Iterator for JotdownIntoBuffer<'a, '
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct RichText(
|
||||
String,
|
||||
#[cfg_attr(feature = "serde", serde(with = "AttrsSerde"))] AttrsOwned,
|
||||
);
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct JotdownItem<'a> {
|
||||
pub indent: Indent,
|
||||
pub buffer: Vec<(&'a str, Attrs<'static>)>,
|
||||
pub buffer: Vec<RichText>,
|
||||
#[cfg_attr(feature = "serde", serde(with = "MetricsSerde"))]
|
||||
pub metrics: Metrics,
|
||||
pub image_url: Option<Cow<'a, str>>,
|
||||
pub url_map: Option<RangeMap<usize, &'a str>>,
|
||||
pub url_map: Option<RangeMap<usize, Cow<'a, str>>>,
|
||||
}
|
||||
|
||||
impl<'a> JotdownItem<'a> {
|
||||
|
@ -154,7 +172,7 @@ impl<'a> JotdownItem<'a> {
|
|||
);
|
||||
buffer.set_rich_text(
|
||||
font_system,
|
||||
self.buffer.iter().cloned(),
|
||||
self.buffer.iter().map(|r| (r.0.as_str(), r.1.as_attrs())),
|
||||
Attrs::new().family(Family::SansSerif),
|
||||
Shaping::Advanced,
|
||||
);
|
||||
|
@ -182,7 +200,9 @@ impl<'a, T: Iterator<Item = Event<'a>>> Iterator for JotdownBufferIter<'a, T> {
|
|||
urls: Vec::new(),
|
||||
};
|
||||
|
||||
let buffer: Vec<(&str, Attrs<'static>)> = (&mut jot).collect();
|
||||
let buffer = (&mut jot)
|
||||
.map(|r| RichText(r.0.to_owned(), AttrsOwned::new(r.1)))
|
||||
.collect::<Vec<_>>();
|
||||
let image_url = jot.image_url;
|
||||
let urls = jot.urls;
|
||||
let added = jot.added;
|
||||
|
@ -196,7 +216,9 @@ impl<'a, T: Iterator<Item = Event<'a>>> Iterator for JotdownBufferIter<'a, T> {
|
|||
url_map: if urls.is_empty() {
|
||||
None
|
||||
} else {
|
||||
RangeMap::try_from_iter(urls.into_iter()).ok()
|
||||
let mut map = RangeMap::new();
|
||||
map.extend(urls.into_iter());
|
||||
Some(map)
|
||||
},
|
||||
buffer,
|
||||
image_url,
|
||||
|
|
195
src/serde_suck.rs
Normal file
195
src/serde_suck.rs
Normal file
|
@ -0,0 +1,195 @@
|
|||
use cosmic_text::{
|
||||
Align, Attrs, AttrsOwned, CacheKeyFlags, Color, FamilyOwned, Metrics, Stretch, Style, Weight,
|
||||
};
|
||||
|
||||
use jotdown::{ListKind, OrderedListNumbering, OrderedListStyle};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Option<ListKind>")]
|
||||
pub enum ListKindOption {
|
||||
Some(#[serde(with = "ListKindSerde")] ListKind),
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "jotdown::ListKind")]
|
||||
pub enum ListKindSerde {
|
||||
Unordered,
|
||||
Ordered {
|
||||
numbering: OrderedListNumbering,
|
||||
style: OrderedListStyle,
|
||||
start: u64,
|
||||
},
|
||||
Task,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "jotdown::OrderedListNumbering")]
|
||||
pub enum OrderedListNumberingSerde {
|
||||
Decimal,
|
||||
AlphaLower,
|
||||
AlphaUpper,
|
||||
RomanLower,
|
||||
RomanUpper,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "jotdown::OrderedListStyle")]
|
||||
pub enum OrderedListStyleSerde {
|
||||
Period,
|
||||
Paren,
|
||||
ParenParen,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Metrics")]
|
||||
pub struct MetricsSerde {
|
||||
pub font_size: f32,
|
||||
pub line_height: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "FamilyOwned")]
|
||||
pub enum FamilySerde {
|
||||
Name(String),
|
||||
Serif,
|
||||
SansSerif,
|
||||
Cursive,
|
||||
Fantasy,
|
||||
Monospace,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Stretch")]
|
||||
pub enum StretchSerde {
|
||||
UltraCondensed,
|
||||
ExtraCondensed,
|
||||
Condensed,
|
||||
SemiCondensed,
|
||||
Normal,
|
||||
SemiExpanded,
|
||||
Expanded,
|
||||
ExtraExpanded,
|
||||
UltraExpanded,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Style")]
|
||||
pub enum StyleSerde {
|
||||
Normal,
|
||||
Italic,
|
||||
Oblique,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Weight")]
|
||||
pub struct WeightSerde(pub u16);
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Color")]
|
||||
pub struct ColorSerde(pub u32);
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Option<Color>")]
|
||||
pub enum ColorOpt {
|
||||
Some(#[serde(with = "ColorSerde")] Color),
|
||||
None,
|
||||
}
|
||||
|
||||
mod cache_key_flags {
|
||||
use cosmic_text::CacheKeyFlags;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
pub fn serialize<S>(_: &CacheKeyFlags, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
().serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<CacheKeyFlags, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let _: () = <()>::deserialize(deserializer)?;
|
||||
Ok(CacheKeyFlags::empty())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "AttrsOwned")]
|
||||
pub struct AttrsSerde {
|
||||
#[serde(with = "ColorOpt")]
|
||||
pub color_opt: Option<Color>,
|
||||
#[serde(with = "FamilySerde")]
|
||||
pub family_owned: FamilyOwned,
|
||||
#[serde(with = "StretchSerde")]
|
||||
pub stretch: Stretch,
|
||||
#[serde(with = "StyleSerde")]
|
||||
pub style: Style,
|
||||
#[serde(with = "WeightSerde")]
|
||||
pub weight: Weight,
|
||||
pub metadata: usize,
|
||||
#[serde(with = "cache_key_flags")]
|
||||
pub cache_key_flags: CacheKeyFlags,
|
||||
}
|
||||
|
||||
impl<'a> From<Attrs<'a>> for AttrsSerde {
|
||||
fn from(value: Attrs<'a>) -> Self {
|
||||
Self {
|
||||
color_opt: value.color_opt,
|
||||
family_owned: FamilyOwned::new(value.family),
|
||||
stretch: value.stretch,
|
||||
style: value.style,
|
||||
weight: value.weight,
|
||||
metadata: value.metadata,
|
||||
cache_key_flags: value.cache_key_flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Option<Align>")]
|
||||
pub enum AlignSerde {
|
||||
Some(#[serde(with = "AlignRef")] Align),
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(remote = "Align")]
|
||||
pub enum AlignRef {
|
||||
Left,
|
||||
Right,
|
||||
Center,
|
||||
Justified,
|
||||
End,
|
||||
}
|
||||
|
||||
impl AttrsSerde {
|
||||
pub fn as_attrs(&self) -> Attrs<'_> {
|
||||
Attrs {
|
||||
color_opt: self.color_opt,
|
||||
family: self.family_owned.as_family(),
|
||||
stretch: self.stretch,
|
||||
style: self.style,
|
||||
weight: self.weight,
|
||||
metadata: self.metadata,
|
||||
cache_key_flags: CacheKeyFlags::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AttrsOwned> for AttrsSerde {
|
||||
fn from(value: AttrsOwned) -> Self {
|
||||
Self {
|
||||
color_opt: value.color_opt,
|
||||
family_owned: value.family_owned,
|
||||
stretch: value.stretch,
|
||||
style: value.style,
|
||||
weight: value.weight,
|
||||
metadata: value.metadata,
|
||||
cache_key_flags: value.cache_key_flags,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue