use thiserror::Error;
#[derive(Debug, Error)]
#[error("{0}")]
pub struct EmbedError(String);
impl EmbedError {
pub fn new<E: std::error::Error>(e: E) -> Self {
Self(e.to_string())
}
pub fn msg(s: impl Into<String>) -> Self {
Self(s.into())
}
}
#[derive(Default)]
pub struct TextEmbedder {
pub(crate) texts: Vec<String>,
}
impl TextEmbedder {
pub fn embed(&mut self, text: String) {
self.texts.push(text);
}
}
pub trait Embed {
fn embed(&self, embedder: &mut TextEmbedder) -> Result<(), EmbedError>;
}
pub fn to_texts(item: impl Embed) -> Result<Vec<String>, EmbedError> {
let mut embedder = TextEmbedder::default();
item.embed(&mut embedder)?;
Ok(embedder.texts)
}
impl Embed for String {
fn embed(&self, e: &mut TextEmbedder) -> Result<(), EmbedError> {
e.embed(self.clone());
Ok(())
}
}
impl Embed for &str {
fn embed(&self, e: &mut TextEmbedder) -> Result<(), EmbedError> {
e.embed(self.to_string());
Ok(())
}
}
impl Embed for serde_json::Value {
fn embed(&self, e: &mut TextEmbedder) -> Result<(), EmbedError> {
e.embed(serde_json::to_string(self).map_err(EmbedError::new)?);
Ok(())
}
}
impl<T: Embed> Embed for &T {
fn embed(&self, e: &mut TextEmbedder) -> Result<(), EmbedError> {
(*self).embed(e)
}
}
impl<T: Embed> Embed for Vec<T> {
fn embed(&self, e: &mut TextEmbedder) -> Result<(), EmbedError> {
for item in self {
item.embed(e)?;
}
Ok(())
}
}
impl<T: Embed> Embed for Option<T> {
fn embed(&self, e: &mut TextEmbedder) -> Result<(), EmbedError> {
if let Some(inner) = self {
inner.embed(e)?;
}
Ok(())
}
}