mongo_embedded/
lib.rs

1pub mod downloader;
2pub mod extractor;
3pub mod process;
4
5use anyhow::Result;
6use std::path::PathBuf;
7use directories::ProjectDirs;
8
9use crate::downloader::{get_download_url, download_file_with_callback, get_os};
10use crate::extractor::extract;
11use crate::process::MongoProcess;
12
13pub use crate::downloader::DownloadProgress;
14
15pub struct MongoEmbedded {
16    pub version: String,
17    pub download_path: PathBuf,
18    pub extract_path: PathBuf,
19    pub db_path: PathBuf,
20    pub port: u16,
21    pub bind_ip: String,
22}
23
24impl MongoEmbedded {
25    pub fn new(version: &str) -> Result<Self> {
26        let proj_dirs = ProjectDirs::from("com", "mongo", "embedded")
27            .ok_or_else(|| anyhow::anyhow!("Could not determine project directories"))?;
28        
29        let cache_dir = proj_dirs.cache_dir();
30        let data_dir = proj_dirs.data_dir();
31
32        Ok(Self {
33            version: version.to_string(),
34            download_path: cache_dir.join("downloads"),
35            extract_path: cache_dir.join("extracted"),
36            db_path: data_dir.join("db"),
37            port: 27017,
38            bind_ip: "127.0.0.1".to_string(),
39        })
40    }
41
42    pub fn set_port(mut self, port: u16) -> Self {
43        self.port = port;
44        self
45    }
46
47    pub fn set_bind_ip(mut self, bind_ip: &str) -> Self {
48        self.bind_ip = bind_ip.to_string();
49        self
50    }
51
52    pub fn set_db_path(mut self, path: PathBuf) -> Self {
53        self.db_path = path;
54        self
55    }
56
57    pub fn is_installed(&self) -> bool {
58        let extract_target = self.extract_path.join(self.version.as_str());
59        extract_target.exists()
60    }
61
62    pub async fn start(&self) -> Result<MongoProcess> {
63        self.start_with_progress(|_| {}).await
64    }
65
66    pub async fn start_with_progress<F>(&self, callback: F) -> Result<MongoProcess>
67    where
68        F: FnMut(DownloadProgress),
69    {
70        let mongo_url = get_download_url(&self.version)?;
71        let download_target = self.download_path.join(&mongo_url.filename);
72
73        if !download_target.exists() {
74            if !self.download_path.exists() {
75                std::fs::create_dir_all(&self.download_path)?;
76            }
77            download_file_with_callback(&mongo_url.url, &download_target, callback).await?;
78        }
79
80        let extract_target = self.extract_path.join(self.version.as_str());
81        if !extract_target.exists() {
82            extract(&download_target, &extract_target)?;
83        }
84
85        let os = get_os()?;
86        
87        MongoProcess::start(&extract_target, self.port, &self.db_path, &os, &self.bind_ip)
88    }
89}
90