Skip to main content

mdbook_termlink/config/
display_mode.rs

1//! How linked glossary terms are rendered in the output HTML.
2
3use std::str::FromStr;
4
5/// Output shape chosen for every linked glossary occurrence.
6///
7/// See the `display-mode` option in the README for the rendered HTML produced
8/// by each variant.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10pub enum DisplayMode {
11    /// `<a href title class>term</a>` — anchor with native browser tooltip.
12    #[default]
13    Link,
14    /// `<abbr title tabindex class>term</abbr>` — tooltip only, no navigation.
15    Tooltip,
16    /// `<a href class><abbr title tabindex>term</abbr></a>` — anchor wrapping
17    /// a semantic abbreviation.
18    Both,
19}
20
21/// Error returned when a string cannot be parsed into a [`DisplayMode`].
22#[derive(Debug, thiserror::Error)]
23#[error("invalid display-mode '{value}'; expected 'link', 'tooltip', or 'both'")]
24pub struct InvalidDisplayMode {
25    /// The verbatim string that failed to parse.
26    pub value: String,
27}
28
29impl FromStr for DisplayMode {
30    type Err = InvalidDisplayMode;
31
32    fn from_str(s: &str) -> Result<Self, Self::Err> {
33        match s {
34            "link" => Ok(Self::Link),
35            "tooltip" => Ok(Self::Tooltip),
36            "both" => Ok(Self::Both),
37            other => Err(InvalidDisplayMode {
38                value: other.to_owned(),
39            }),
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn parses_each_variant() {
50        assert_eq!("link".parse::<DisplayMode>().unwrap(), DisplayMode::Link);
51        assert_eq!(
52            "tooltip".parse::<DisplayMode>().unwrap(),
53            DisplayMode::Tooltip
54        );
55        assert_eq!("both".parse::<DisplayMode>().unwrap(), DisplayMode::Both);
56    }
57
58    #[test]
59    fn rejects_unknown_value() {
60        let err = "nonsense".parse::<DisplayMode>().unwrap_err();
61        assert_eq!(err.value, "nonsense");
62        assert!(err.to_string().contains("nonsense"));
63    }
64
65    #[test]
66    fn rejects_empty() {
67        assert!("".parse::<DisplayMode>().is_err());
68    }
69
70    #[test]
71    fn default_is_link() {
72        assert_eq!(DisplayMode::default(), DisplayMode::Link);
73    }
74}