use std::path::{Path, PathBuf};
use std::sync::Arc;
#[derive(Clone)]
pub enum ModelSource {
Path(PathBuf),
Memory(Arc<[u8]>),
}
impl ModelSource {
pub fn as_path(&self) -> Option<&Path> {
match self {
Self::Path(p) => Some(p),
Self::Memory(_) => None,
}
}
pub fn display_path(&self) -> PathBuf {
match self {
Self::Path(p) => p.clone(),
Self::Memory(bytes) => PathBuf::from(format!("<in-memory: {} bytes>", bytes.len())),
}
}
}
impl std::fmt::Debug for ModelSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Path(p) => f.debug_tuple("Path").field(p).finish(),
Self::Memory(bytes) => f.debug_struct("Memory").field("len", &bytes.len()).finish(),
}
}
}
impl From<&ModelSource> for ModelSource {
fn from(source: &ModelSource) -> Self {
source.clone()
}
}
impl From<PathBuf> for ModelSource {
fn from(p: PathBuf) -> Self {
Self::Path(p)
}
}
impl From<&PathBuf> for ModelSource {
fn from(p: &PathBuf) -> Self {
Self::Path(p.clone())
}
}
impl From<&Path> for ModelSource {
fn from(p: &Path) -> Self {
Self::Path(p.to_path_buf())
}
}
impl From<String> for ModelSource {
fn from(p: String) -> Self {
Self::Path(PathBuf::from(p))
}
}
impl From<&str> for ModelSource {
fn from(p: &str) -> Self {
Self::Path(PathBuf::from(p))
}
}
impl From<Vec<u8>> for ModelSource {
fn from(bytes: Vec<u8>) -> Self {
Self::Memory(bytes.into())
}
}
impl From<Arc<[u8]>> for ModelSource {
fn from(bytes: Arc<[u8]>) -> Self {
Self::Memory(bytes)
}
}
impl From<&'static [u8]> for ModelSource {
fn from(bytes: &'static [u8]) -> Self {
Self::Memory(bytes.into())
}
}
impl<const N: usize> From<&'static [u8; N]> for ModelSource {
fn from(bytes: &'static [u8; N]) -> Self {
Self::Memory(bytes.as_slice().into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn path_like_inputs_become_path_sources() {
for source in [
ModelSource::from("a/b.onnx"),
ModelSource::from(String::from("a/b.onnx")),
ModelSource::from(PathBuf::from("a/b.onnx")),
ModelSource::from(Path::new("a/b.onnx")),
] {
assert_eq!(source.as_path(), Some(Path::new("a/b.onnx")));
}
}
#[test]
fn byte_inputs_become_memory_sources() {
static EMBEDDED: [u8; 4] = [1, 2, 3, 4];
for source in [
ModelSource::from(vec![1u8, 2, 3, 4]),
ModelSource::from(&EMBEDDED),
ModelSource::from(EMBEDDED.as_slice()),
] {
assert!(source.as_path().is_none());
let ModelSource::Memory(bytes) = source else {
panic!("expected memory source");
};
assert_eq!(&bytes[..], &[1, 2, 3, 4]);
}
}
}