Skip to main content

percy_preview/
lib.rs

1//! Preview view components.
2
3#![deny(missing_docs)]
4
5use std::cell::RefCell;
6use std::rc::Rc;
7
8use virtual_node::VirtualNode;
9
10pub use self::rerender::Rerender;
11
12mod rerender;
13
14/// Describes a view component preview.
15pub struct Preview {
16    /// The name of this preview
17    name: String,
18    /// A description of the preview.
19    /// This gets displayed above the preview.
20    description: Option<String>,
21    /// A url friendly version of the name.
22    name_url_friendly: UrlFriendlyString,
23    /// Render the preview
24    renderer: Rc<RefCell<dyn FnMut() -> VirtualNode>>,
25}
26
27/// A string that only contains letters, numbers, hyphens and underscores.
28struct UrlFriendlyString(String);
29
30impl Preview {
31    /// Create a new Preview.
32    pub fn new<S: ToString>(name: S, render: Rc<RefCell<dyn FnMut() -> VirtualNode>>) -> Self {
33        let name_url_friendly = UrlFriendlyString::new(name.to_string());
34        Preview {
35            name: name.to_string(),
36            description: None,
37            name_url_friendly,
38            renderer: render,
39        }
40    }
41
42    /// The name of the preview.
43    pub fn name(&self) -> &String {
44        &self.name
45    }
46
47    /// A URL friendly version of the name.
48    pub fn name_url_friendly(&self) -> &String {
49        &self.name_url_friendly.0
50    }
51
52    /// The preview's description.
53    pub fn description(&self) -> &Option<String> {
54        &self.description
55    }
56
57    /// The preview's description.
58    pub fn set_description(&mut self, description: Option<String>) {
59        self.description = description;
60    }
61
62    /// Returns a function that can be used to render the preview.
63    pub fn renderer(&self) -> &Rc<RefCell<dyn FnMut() -> VirtualNode>> {
64        &self.renderer
65    }
66}
67
68impl UrlFriendlyString {
69    /// Replaces non alphanumeric characters with hyphens.
70    pub fn new<S: ToString>(string: S) -> Self {
71        let string = string.to_string();
72        let string = string.replace(" ", "-");
73
74        let url_friendly_string: String = string
75            .chars()
76            .filter_map(|char| {
77                if char == '-' || char == '_' {
78                    return Some(char);
79                }
80
81                if !char.is_alphanumeric() {
82                    return None;
83                }
84
85                return Some(char);
86            })
87            .collect();
88
89        UrlFriendlyString(url_friendly_string.to_lowercase())
90    }
91}