Skip to main content

oak_hover/
lib.rs

1#![feature(new_range_api)]
2#![warn(missing_docs)]
3#![doc = include_str!("readme.md")]
4
5use core::range::Range;
6use oak_core::{language::Language, tree::RedNode};
7
8/// Represents hover information.
9#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Hover {
12    /// The hover's content as a markdown string.
13    pub contents: String,
14    /// An optional span to which this hover applies.
15    #[cfg_attr(feature = "serde", serde(with = "serde_range_opt", bound(serialize = "", deserialize = "")))]
16    pub range: Option<Range<usize>>,
17}
18
19#[cfg(feature = "serde")]
20mod serde_range_opt {
21    use super::*;
22    use serde::{Deserialize, Deserializer, Serializer};
23
24    pub fn serialize<S>(value: &Option<Range<usize>>, serializer: S) -> Result<S::Ok, S::Error>
25    where
26        S: Serializer,
27    {
28        match value {
29            Some(range) => oak_core::serde_range::serialize(range, serializer),
30            None => serializer.serialize_none(),
31        }
32    }
33
34    #[derive(Deserialize)]
35    struct RangeDef {
36        start: usize,
37        end: usize,
38    }
39
40    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Range<usize>>, D::Error>
41    where
42        D: Deserializer<'de>,
43    {
44        let opt: Option<RangeDef> = Option::deserialize(deserializer)?;
45        Ok(opt.map(|def| Range { start: def.start, end: def.end }))
46    }
47}
48
49/// Trait for languages that support hover information.
50pub trait HoverProvider<L: Language> {
51    /// Returns hover information at the given range.
52    fn hover(&self, root: &RedNode<L>, range: Range<usize>) -> Option<Hover>;
53}