Add serde support
This commit is contained in:
		
					parent
					
						
							
								7f245acf66
							
						
					
				
			
			
				commit
				
					
						b3339bc4c7
					
				
			
		
					 4 changed files with 237 additions and 35 deletions
				
			
		
							
								
								
									
										30
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										30
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -2,12 +2,6 @@
 | 
			
		|||
# It is not intended for manual editing.
 | 
			
		||||
version = 3
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "autocfg"
 | 
			
		||||
version = "1.2.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bitflags"
 | 
			
		||||
version = "2.5.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +35,8 @@ dependencies = [
 | 
			
		|||
 "cosmic-text",
 | 
			
		||||
 "jotdown",
 | 
			
		||||
 "log",
 | 
			
		||||
 "range-map",
 | 
			
		||||
 "rangemap",
 | 
			
		||||
 "serde",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -158,15 +153,6 @@ dependencies = [
 | 
			
		|||
 "libc",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "num-traits"
 | 
			
		||||
version = "0.2.18"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "autocfg",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "1.0.79"
 | 
			
		||||
| 
						 | 
				
			
			@ -185,20 +171,14 @@ dependencies = [
 | 
			
		|||
 "proc-macro2",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "range-map"
 | 
			
		||||
version = "0.2.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "12a5a2d6c7039059af621472a4389be1215a816df61aa4d531cfe85264aee95f"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "num-traits",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rangemap"
 | 
			
		||||
version = "1.5.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "serde",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "read-fonts"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,4 +9,9 @@ edition = "2021"
 | 
			
		|||
cosmic-text = "0.11.2"
 | 
			
		||||
jotdown = { git = "https://git.nations.lol/fnmain/jotdown" }
 | 
			
		||||
log = "0.4.21"
 | 
			
		||||
range-map = "0.2.0"
 | 
			
		||||
serde = { version = "1.0.197", features = ["derive"], optional = true }
 | 
			
		||||
rangemap = "1.5.1"
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
default = ["serde"]
 | 
			
		||||
serde = ["dep:serde", "rangemap/serde1"]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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