forge_doc/preprocessor/
deployments.rs
1use super::{Preprocessor, PreprocessorId};
2use crate::{Document, PreprocessorOutput};
3use alloy_primitives::Address;
4use std::{
5 fs,
6 path::{Path, PathBuf},
7};
8
9pub const DEPLOYMENTS_ID: PreprocessorId = PreprocessorId("deployments");
11
12#[derive(Debug)]
16pub struct Deployments {
17 pub root: PathBuf,
19 pub deployments: Option<PathBuf>,
21}
22
23#[derive(Clone, Debug, serde::Deserialize)]
25pub struct Deployment {
26 pub address: Address,
28 pub network: Option<String>,
30}
31
32impl Preprocessor for Deployments {
33 fn id(&self) -> PreprocessorId {
34 DEPLOYMENTS_ID
35 }
36
37 fn preprocess(&self, documents: Vec<Document>) -> Result<Vec<Document>, eyre::Error> {
38 let deployments_dir =
39 self.root.join(self.deployments.as_deref().unwrap_or(Path::new("deployments")));
40
41 let networks = fs::read_dir(&deployments_dir)?
43 .map(|entry| {
44 let entry = entry?;
45 let path = entry.path();
46 if entry.file_type()?.is_dir() {
47 entry
48 .file_name()
49 .into_string()
50 .map_err(|e| eyre::eyre!("failed to extract directory name: {e:?}"))
51 } else {
52 eyre::bail!("not a directory: {}", path.display())
53 }
54 })
55 .collect::<Result<Vec<_>, _>>()?;
56
57 for document in &documents {
59 let mut deployments = Vec::default();
60
61 for network in &networks {
63 let mut item_path_clone = document.item_path.clone();
65 item_path_clone.set_extension("json");
66
67 let deployment_path =
69 deployments_dir.join(network).join(item_path_clone.file_name().ok_or_else(
70 || eyre::eyre!("Failed to extract file name from item path"),
71 )?);
72
73 let mut deployment: Deployment =
76 serde_json::from_str(&fs::read_to_string(deployment_path)?)?;
77 deployment.network = Some(network.clone());
78 deployments.push(deployment);
79 }
80
81 if !deployments.is_empty() {
84 document.add_context(self.id(), PreprocessorOutput::Deployments(deployments));
85 }
86 }
87
88 Ok(documents)
89 }
90}