git.delta.rocks / jrsonnet / refs/commits / bde2637fa85f

difftreelog

source

crates/jrsonnet-parser/src/source.rs2.1 KiBsourcehistory
1use std::{2	borrow::Cow,3	fmt,4	path::{Component, Path, PathBuf},5	rc::Rc,6};78use jrsonnet_gcmodule::{Trace, Tracer};9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};1112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]13#[derive(PartialEq, Eq, Debug, Hash)]14enum Inner {15	Real(PathBuf),16	Virtual(Cow<'static, str>),17}1819/// Either real file, or virtual20/// Hash of FileName always have same value as raw Path, to make it possible to use with raw_entry_mut21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]22#[derive(Clone, PartialEq, Eq, Debug)]23pub struct Source(Rc<Inner>);24static_assertions::assert_eq_size!(Source, *const ());2526impl Trace for Source {27	fn trace(&self, _tracer: &mut Tracer) {}2829	fn is_type_tracked() -> bool {30		false31	}32}3334impl Source {35	/// Fails when path contains inner /../ or /./ references, or not absolute36	pub fn new(path: PathBuf) -> Option<Self> {37		if !path.is_absolute()38			|| path39				.components()40				.any(|c| matches!(c, Component::CurDir | Component::ParentDir))41		{42			return None;43		}44		Some(Self(Rc::new(Inner::Real(path))))45	}4647	pub fn new_virtual(n: Cow<'static, str>) -> Self {48		Self(Rc::new(Inner::Virtual(n)))49	}5051	pub fn short_display(&self) -> ShortDisplay {52		ShortDisplay(self.clone())53	}54	pub fn full_path(&self) -> String {55		match self.inner() {56			Inner::Real(r) => r.display().to_string(),57			Inner::Virtual(v) => v.to_string(),58		}59	}6061	/// Returns None if file is virtual62	pub fn path(&self) -> Option<&Path> {63		match self.inner() {64			Inner::Real(r) => Some(r),65			Inner::Virtual(_) => None,66		}67	}68	pub fn repr(&self) -> Result<&Path, &str> {69		match self.inner() {70			Inner::Real(r) => Ok(r),71			Inner::Virtual(v) => Err(v.as_ref()),72		}73	}7475	fn inner(&self) -> &Inner {76		&self.0 as &Inner77	}78}79pub struct ShortDisplay(Source);80impl fmt::Display for ShortDisplay {81	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {82		match &self.0 .0 as &Inner {83			Inner::Real(r) => {84				write!(85					f,86					"{}",87					r.file_name().expect("path is valid").to_string_lossy()88				)89			}90			Inner::Virtual(n) => write!(f, "{}", n),91		}92	}93}