Skip to main content

use_vite/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::fmt;
5use std::error::Error;
6
7macro_rules! text_newtype {
8    ($name:ident) => {
9        #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10        pub struct $name(String);
11
12        impl $name {
13            /// Creates non-empty Vite text metadata.
14            ///
15            /// # Errors
16            ///
17            /// Returns [`ViteTextError::Empty`] when `input` is empty after trimming.
18            pub fn new(input: &str) -> Result<Self, ViteTextError> {
19                let trimmed = input.trim();
20                if trimmed.is_empty() {
21                    Err(ViteTextError::Empty)
22                } else {
23                    Ok(Self(trimmed.to_string()))
24                }
25            }
26
27            /// Returns the stored text.
28            #[must_use]
29            pub fn as_str(&self) -> &str {
30                &self.0
31            }
32        }
33    };
34}
35
36/// Common Vite config file labels.
37#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
38pub enum ViteConfigFile {
39    JavaScript,
40    TypeScript,
41    Mjs,
42    Mts,
43}
44
45impl ViteConfigFile {
46    /// Returns the config file label.
47    #[must_use]
48    pub const fn as_str(self) -> &'static str {
49        match self {
50            Self::JavaScript => "vite.config.js",
51            Self::TypeScript => "vite.config.ts",
52            Self::Mjs => "vite.config.mjs",
53            Self::Mts => "vite.config.mts",
54        }
55    }
56}
57
58text_newtype!(ViteMode);
59text_newtype!(VitePluginName);
60
61/// Vite framework preset labels.
62#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
63pub enum ViteFrameworkPreset {
64    React,
65    Vue,
66    Svelte,
67    Vanilla,
68    Lit,
69    Preact,
70    Solid,
71    Qwik,
72}
73
74impl ViteFrameworkPreset {
75    /// Returns the preset label.
76    #[must_use]
77    pub const fn as_str(self) -> &'static str {
78        match self {
79            Self::React => "react",
80            Self::Vue => "vue",
81            Self::Svelte => "svelte",
82            Self::Vanilla => "vanilla",
83            Self::Lit => "lit",
84            Self::Preact => "preact",
85            Self::Solid => "solid",
86            Self::Qwik => "qwik",
87        }
88    }
89}
90
91/// Error returned when Vite text metadata is empty.
92#[derive(Clone, Copy, Debug, Eq, PartialEq)]
93pub enum ViteTextError {
94    Empty,
95}
96
97impl fmt::Display for ViteTextError {
98    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
99        formatter.write_str("Vite metadata text cannot be empty")
100    }
101}
102
103impl Error for ViteTextError {}
104
105#[cfg(test)]
106mod tests {
107    use super::{ViteConfigFile, ViteFrameworkPreset, ViteMode};
108
109    #[test]
110    fn models_vite_metadata() -> Result<(), Box<dyn std::error::Error>> {
111        assert_eq!(ViteConfigFile::TypeScript.as_str(), "vite.config.ts");
112        assert_eq!(ViteFrameworkPreset::React.as_str(), "react");
113        assert_eq!(ViteMode::new("development")?.as_str(), "development");
114        Ok(())
115    }
116}