diff --git a/Cargo.toml b/Cargo.toml index c06c176..3df02df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ generational-arena = "0.2" crossterm = "0.27.0" [dependencies.partial-pretty-printer] git = "https://github.com/justinpombrio/partial-pretty-printer" - version = "0.3.0" + version = "0.4.0" [dependencies.no-nonsense-flamegraphs] version = "0.2.*" git = "https://github.com/justinpombrio/no-nonsense-flamegraphs" diff --git a/src/pretty_doc.rs b/src/pretty_doc.rs index 2f1b148..2c1911f 100644 --- a/src/pretty_doc.rs +++ b/src/pretty_doc.rs @@ -17,6 +17,12 @@ fn get_text_notation() -> &'static ValidNotation { }) } +#[derive(thiserror::Error, Debug)] +pub enum PrettyDocError { + #[error("No source notation available for language '{0}'")] + NoSourceNotation(String), +} + #[derive(Clone, Copy)] pub struct DocRef<'d> { storage: &'d Storage, @@ -58,25 +64,26 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> { type Style = Style; type StyleLabel = StyleLabel; type Condition = Condition; + type Error = PrettyDocError; - fn id(self) -> (NodeId, u16) { + fn id(self) -> Result<(NodeId, u16), Self::Error> { let id = self.node.id(self.storage); - match self.text_pos { + Ok(match self.text_pos { None => (id, 0), Some(CursorHalf::Left) => (id, 1), Some(CursorHalf::Right) => (id, 2), - } + }) } - fn notation(self) -> &'d ValidNotation { - match self.text_pos { + fn notation(self) -> Result<&'d ValidNotation, Self::Error> { + Ok(match self.text_pos { None => self.node.notation(self.storage), Some(_) => get_text_notation(), - } + }) } - fn condition(self, condition: &Condition) -> bool { - match condition { + fn condition(self, condition: &Condition) -> Result { + Ok(match condition { Condition::IsEmptyText => self .node .text(self.storage) @@ -85,22 +92,22 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> { Condition::IsCommentOrWs => self.node.is_comment_or_ws(self.storage), Condition::NeedsSeparator => { if self.node.is_comment_or_ws(self.storage) { - return false; + return Ok(false); } let mut sibling = self.node; while let Some(next_sibling) = sibling.next_sibling(self.storage) { if !next_sibling.is_comment_or_ws(self.storage) { - return true; + return Ok(true); } sibling = next_sibling; } false } - } + }) } - fn lookup_style(self, style_label: StyleLabel) -> Style { - match style_label { + fn lookup_style(self, style_label: StyleLabel) -> Result { + Ok(match style_label { StyleLabel::Hole => HOLE_STYLE, StyleLabel::Open => { let parent = self.cursor_loc.parent_node(self.storage); @@ -134,11 +141,11 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> { cursor: None, is_hole: false, }, - } + }) } - fn node_style(self) -> Style { - if self.text_pos.is_some() { + fn node_style(self) -> Result { + Ok(if self.text_pos.is_some() { Style::default() } else if self.cursor_loc.left_node(self.storage) == Some(self.node) { LEFT_CURSOR_STYLE @@ -146,63 +153,63 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> { RIGHT_CURSOR_STYLE } else { Style::default() - } + }) } - fn num_children(self) -> Option { - if self.on_virtual_text_parent() { + fn num_children(self) -> Result, Self::Error> { + Ok(if self.on_virtual_text_parent() { Some(2) } else { self.node.num_children(self.storage) - } + }) } - fn unwrap_text(self) -> &'d str { + fn unwrap_text(self) -> Result<&'d str, Self::Error> { let text = &self.node.text(self.storage).bug(); - match self.text_pos { + Ok(match self.text_pos { None => bug!("DocRef::unwrap_text non-virtual text"), Some(CursorHalf::Left) => text.as_split_str(self.text_index()).0, Some(CursorHalf::Right) => text.as_split_str(self.text_index()).1, - } + }) } - fn unwrap_child(self, i: usize) -> Self { + fn unwrap_child(self, i: usize) -> Result { if self.on_virtual_text_parent() { let cursor_half = match i { 0 => CursorHalf::Left, 1 => CursorHalf::Right, _ => bug!("DocRef::unwrap_child virtual text child OOB"), }; - DocRef { + Ok(DocRef { text_pos: Some(cursor_half), ..self - } + }) } else { let child = self.node.nth_child(self.storage, i).bug(); - DocRef { + Ok(DocRef { node: child, ..self - } + }) } } - fn unwrap_last_child(self) -> Self { + fn unwrap_last_child(self) -> Result { if self.on_virtual_text_parent() { - DocRef { + Ok(DocRef { text_pos: Some(CursorHalf::Right), ..self - } + }) } else { let last_child = self.node.last_child(self.storage).bug(); - DocRef { + Ok(DocRef { node: last_child, ..self - } + }) } } - fn unwrap_prev_sibling(self, _: Self, _: usize) -> Self { - match self.text_pos { + fn unwrap_prev_sibling(self, _: Self, _: usize) -> Result { + Ok(match self.text_pos { Some(CursorHalf::Left) => bug!("unwrap_prev_sibling: virtual text OOB"), Some(CursorHalf::Right) => DocRef { text_pos: Some(CursorHalf::Left), @@ -215,7 +222,7 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> { ..self } } - } + }) } }