1use kmp_adapter_embedded::StorageEngine;
12use kmp_domain::PortError;
13
14pub const ENGINE_ENV: &str = "KMP_MCP_ENGINE";
18
19pub fn parse_engine(value: &str) -> Result<StorageEngine, PortError> {
22 match value.trim().to_ascii_lowercase().as_str() {
23 "redb" => Ok(StorageEngine::Redb),
24 "sqlite" => Ok(StorageEngine::Sqlite),
25 other => Err(PortError::InvalidState(format!(
26 "unknown storage engine `{other}`; {ENGINE_ENV} accepts `redb` or `sqlite`"
27 ))),
28 }
29}
30
31pub fn resolve_engine_from_env() -> Result<Option<StorageEngine>, PortError> {
35 match std::env::var(ENGINE_ENV) {
36 Ok(value) if !value.trim().is_empty() => parse_engine(&value).map(Some),
37 _ => Ok(None),
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn engine_names_are_case_insensitive_and_trimmed() {
47 assert_eq!(
48 parse_engine("redb").expect("redb parses"),
49 StorageEngine::Redb
50 );
51 assert_eq!(
52 parse_engine(" SQLite ").expect("sqlite parses"),
53 StorageEngine::Sqlite
54 );
55 }
56
57 #[test]
58 fn unknown_engine_names_the_variable_and_the_choices() {
59 let error = parse_engine("postgres").expect_err("not an embedded engine");
60 let message = error.to_string();
61 assert!(message.contains("postgres"), "{message}");
62 assert!(message.contains(ENGINE_ENV), "{message}");
63 assert!(message.contains("`redb` or `sqlite`"), "{message}");
64 }
65}