1use std::path::{Path, PathBuf};
2use std::sync::Arc;
3
4use crate::{new_error, Result};
5
6#[derive(Debug, Clone)]
10pub struct Script {
11 content: Arc<str>,
13 base_path: Option<PathBuf>,
15}
16
17impl Script {
18 pub fn from_content(content: impl Into<String>) -> Self {
20 Self {
22 content: Arc::from(content.into()),
23 base_path: None,
24 }
25 }
26
27 pub fn from_file(path: impl AsRef<Path>) -> Result<Self> {
31 let path = path.as_ref();
32
33 let content = std::fs::read_to_string(path)
34 .map_err(|e| new_error!("Failed to read script from '{}': {}", path.display(), e))?;
35
36 let base_path = path.parent().map(|p| p.to_path_buf());
37 Ok(Self {
38 content: Arc::from(content),
39 base_path,
40 })
41 }
42
43 pub fn with_virtual_base(mut self, path: impl AsRef<str>) -> Self {
45 self.base_path = Some(PathBuf::from(path.as_ref()));
46 self
47 }
48
49 pub fn content(&self) -> &str {
51 &self.content
52 }
53
54 pub fn base_path(&self) -> Option<&Path> {
56 self.base_path.as_deref()
57 }
58}
59
60impl From<String> for Script {
61 fn from(content: String) -> Self {
62 Self::from_content(content)
63 }
64}
65
66impl From<&str> for Script {
67 fn from(content: &str) -> Self {
68 Self::from_content(content)
69 }
70}
71
72impl TryFrom<&Path> for Script {
73 type Error = hyperlight_host::HyperlightError;
74 fn try_from(path: &Path) -> Result<Self> {
75 Self::from_file(path)
76 }
77}