Skip to main content

yazi_shared/
non_empty_string.rs

1use std::{borrow::Borrow, ffi::{OsStr, OsString}, fmt::{Display, Formatter}, ops::Deref};
2
3use serde::{Deserialize, Deserializer, Serialize};
4
5#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
6#[serde(transparent)]
7pub struct NonEmptyString(String);
8
9impl NonEmptyString {
10	#[inline]
11	pub fn new(value: String) -> Option<Self> {
12		Some(NonEmptyString(value)).filter(|s| !s.is_empty())
13	}
14}
15
16impl Deref for NonEmptyString {
17	type Target = str;
18
19	#[inline]
20	fn deref(&self) -> &Self::Target { &self.0 }
21}
22
23impl Borrow<str> for NonEmptyString {
24	#[inline]
25	fn borrow(&self) -> &str { &self.0 }
26}
27
28impl Borrow<String> for NonEmptyString {
29	#[inline]
30	fn borrow(&self) -> &String { &self.0 }
31}
32
33impl AsRef<str> for NonEmptyString {
34	#[inline]
35	fn as_ref(&self) -> &str { &self.0 }
36}
37
38impl AsRef<OsStr> for NonEmptyString {
39	#[inline]
40	fn as_ref(&self) -> &OsStr { self.0.as_ref() }
41}
42
43impl Display for NonEmptyString {
44	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.0, f) }
45}
46
47impl From<NonEmptyString> for String {
48	#[inline]
49	fn from(value: NonEmptyString) -> Self { value.0 }
50}
51
52impl From<NonEmptyString> for OsString {
53	#[inline]
54	fn from(value: NonEmptyString) -> Self { value.0.into() }
55}
56
57impl<'de> Deserialize<'de> for NonEmptyString {
58	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
59		let value = String::deserialize(deserializer)?;
60		Self::new(value).ok_or_else(|| serde::de::Error::custom("must be a non-empty string"))
61	}
62}