workspacer_interface/
crate_handle_interface.rs

1// ---------------- [ File: src/crate_handle_interface.rs ]
2crate::ix!();
3
4pub trait CrateHandleInterface<P>
5: ValidateIntegrity<Error=CrateError>
6+ Send
7+ Sync
8+ ReadFileString
9+ EnsureGitClean<Error=GitError>
10+ NameAllFiles<Error=CrateError>
11+ PinWildcardDependencies<Error=CrateError>
12+ PinAllWildcardDependencies<Error=CrateError>
13+ ReadyForCargoPublish<Error=CrateError>
14+ CheckIfSrcDirectoryContainsValidFiles
15+ CheckIfReadmeExists
16+ GetReadmePath
17+ GetSourceFilesWithExclusions
18+ GetTestFiles
19+ HasTestsDirectory
20+ GetFilesInDirectory
21+ GetFilesInDirectoryWithExclusions
22+ HasCargoToml
23+ AsRef<Path>
24+ AsyncTryFrom<P,Error=CrateError>
25where
26    for<'async_trait> 
27    P
28    : HasCargoTomlPathBuf 
29    + AsRef<Path> 
30    + Send 
31    + Sync
32    + 'async_trait,
33
34    CrateError: From<<P as HasCargoTomlPathBuf>::Error>,
35{}
36
37/// We add a new method to CrateHandleInterface so we can read file text from 
38/// an in-memory mock or from the real filesystem. For your real code, 
39/// you might implement it differently.
40#[async_trait]
41pub trait ReadFileString {
42    async fn read_file_string(&self, path: &Path) -> Result<String, CrateError>;
43}
44
45// A trait for "naming all .rs files" with a comment tag
46#[async_trait]
47pub trait NameAllFiles {
48    type Error;
49
50    /// Remove old `// ------ [ File: ... ]` lines and prepend a new one
51    /// naming each `.rs` file in either a single crate or an entire workspace.
52    async fn name_all_files(&self) -> Result<(), Self::Error>;
53}
54
55#[async_trait]
56pub trait GetTestFiles {
57
58    async fn test_files(&self) -> Result<Vec<PathBuf>, CrateError>;
59}
60
61pub trait HasTestsDirectory {
62
63    fn has_tests_directory(&self) -> bool;
64}
65
66pub trait CheckIfReadmeExists {
67
68    fn check_readme_exists(&self) -> Result<(), CrateError>;
69}
70
71#[async_trait]
72pub trait GetReadmePath {
73
74    async fn readme_path(&self) -> Result<Option<PathBuf>, CrateError>;
75}
76
77pub trait HasCargoToml {
78
79    fn cargo_toml<'a>(&'a self) -> &'a dyn CargoTomlInterface;
80}
81
82#[async_trait]
83pub trait HasCargoTomlPathBuf {
84
85    type Error;
86
87    async fn cargo_toml_path_buf(&self) -> Result<PathBuf, Self::Error>;
88}
89
90#[async_trait]
91impl<P> HasCargoTomlPathBuf for P 
92where for <'async_trait> P: AsRef<Path> + Send + Sync + 'async_trait
93{
94    type Error = CrateError;
95
96    /// Asynchronously returns the path to the `Cargo.toml`
97    async fn cargo_toml_path_buf(&self) -> Result<PathBuf, Self::Error> 
98    {
99        let cargo_path = self.as_ref().join("Cargo.toml");
100        if fs::metadata(&cargo_path).await.is_ok() {
101            Ok(cargo_path)
102        } else {
103            Err(CrateError::FileNotFound {
104                missing_file: cargo_path,
105            })
106        }
107    }
108}
109
110pub trait CheckIfSrcDirectoryContainsValidFiles {
111
112    fn check_src_directory_contains_valid_files(&self) -> Result<(), CrateError>;
113}
114
115#[async_trait]
116pub trait GetSourceFilesWithExclusions {
117
118    async fn source_files_excluding(&self, exclude_files: &[&str]) -> Result<Vec<PathBuf>, CrateError>;
119}
120
121#[async_trait]
122pub trait GetFilesInDirectory {
123
124    async fn get_files_in_dir(&self, dir_name: &str, extension: &str) 
125        -> Result<Vec<PathBuf>, CrateError>;
126}
127
128#[async_trait]
129pub trait GetFilesInDirectoryWithExclusions {
130
131    async fn get_files_in_dir_with_exclusions(
132        &self,
133        dir_name: &str,
134        extension: &str,
135        exclude_files: &[&str]
136    ) -> Result<Vec<PathBuf>, CrateError>;
137}
138
139/// Trait for checking if a component is ready for Cargo publishing
140#[async_trait]
141pub trait ReadyForCargoPublish {
142
143    type Error;
144
145    /// Checks if the crate is ready for Cargo publishing
146    async fn ready_for_cargo_publish(&self) -> Result<(), Self::Error>;
147}