use crate::error::RuChatError;
use ollama_rs::models::ModelOptions;
use serde_json::Value;
async fn read_options_file(options_path: &str) -> Result<Value, RuChatError> {
let options = std::fs::read_to_string(options_path)?;
let options = serde_json::from_str(&options)?;
Ok(options)
}
pub(crate) async fn get_options(config: &Option<String>) -> Result<ModelOptions, RuChatError> {
if let Some(options_path) = config {
let mut defaults = serde_json::to_value(ModelOptions::default())?;
if let Value::Object(ref mut defaults) = defaults {
let updates = read_options_file(options_path).await?;
if let Value::Object(config_updates) = updates {
for (k, v) in config_updates.into_iter() {
if defaults.contains_key(&k) && !v.is_null() {
defaults[&k] = v.clone();
}
}
}
}
serde_json::from_value(defaults).map_err(RuChatError::SerdeError)
} else {
Ok(ModelOptions::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::path::Path;
#[tokio::test]
async fn test_read_options_file() {
let path = "test_options.json";
fs::write(path, r#"{\"option1\": \"value1\"}"#).unwrap();
let result = read_options_file(path).await;
assert!(result.is_ok());
let value = result.unwrap();
assert_eq!(value["option1"], "value1");
fs::remove_file(path).unwrap();
}
#[tokio::test]
async fn test_get_options_with_file() {
let path = "test_options.json";
fs::write(path, r#"{\"option1\": \"value1\"}"#).unwrap();
let config = Some(path.to_string());
let result = get_options(&config).await;
assert!(result.is_ok());
fs::remove_file(path).unwrap();
}
#[tokio::test]
async fn test_get_options_without_file() {
let config = None;
let result = get_options(&config).await;
assert!(result.is_ok());
}
}