use std::path::PathBuf;
use crate::Result;
pub trait Source: Send + Sync + std::fmt::Debug {
fn name(&self) -> Option<&str> {
None
}
fn content(&self) -> Box<&str>;
}
impl Source for [u8] {
fn content(&self) -> Box<&str> {
Box::new(std::str::from_utf8(self).unwrap())
}
}
impl Source for &[u8] {
fn content(&self) -> Box<&str> {
<[u8] as Source>::content(self)
}
}
impl Source for Vec<u8> {
fn content(&self) -> Box<&str> {
<[u8] as Source>::content(self)
}
}
impl Source for str {
fn content(&self) -> Box<&str> {
<[u8] as Source>::content(self.as_bytes())
}
}
impl Source for &str {
fn content(&self) -> Box<&str> {
<str as Source>::content(self)
}
}
impl Source for String {
fn content(&self) -> Box<&str> {
<str as Source>::content(self)
}
}
impl Source for &String {
fn content(&self) -> Box<&str> {
<String as Source>::content(self)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StringSource {
pub content: String,
}
impl StringSource {
pub fn new(content: String) -> Self {
Self { content }
}
}
impl Source for StringSource {
fn name(&self) -> Option<&str> {
None
}
fn content(&self) -> Box<&str> {
Box::new(self.content.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NamedSource {
pub name: String,
pub content: String,
}
impl NamedSource {
pub fn new(name: impl Into<String>, content: impl Into<String>) -> Self {
Self {
name: name.into(),
content: content.into(),
}
}
pub fn from_file(path: PathBuf) -> Result<NamedSource> {
let name = path.to_string_lossy().to_string();
let content = std::fs::read_to_string(path)?;
Ok(NamedSource { name, content })
}
}
impl Source for NamedSource {
fn name(&self) -> Option<&str> {
Some(self.name.as_str())
}
fn content(&self) -> Box<&str> {
Box::new(self.content.as_str())
}
}