1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use serde::{Deserialize, Serialize};
/// Request body for POST /api/pull endpoint.
///
/// Downloads a model from the Ollama registry.
///
/// # JSON Examples
///
/// Minimal request:
/// ```json
/// {
/// "model": "llama3.2:latest"
/// }
/// ```
///
/// Full request with options:
/// ```json
/// {
/// "model": "llama3.2:latest",
/// "insecure": false,
/// "stream": false
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PullRequest {
/// Name of the model to download (e.g., "llama3.2:latest", "gemma:7b")
pub model: String,
/// Allow downloading over insecure connections (without TLS verification)
#[serde(skip_serializing_if = "Option::is_none")]
pub insecure: Option<bool>,
/// Stream progress updates. Default: true in Ollama, but we set false for v0.1.0
#[serde(skip_serializing_if = "Option::is_none")]
stream: Option<bool>,
}
impl PullRequest {
/// Create a new pull request for the specified model.
///
/// The request is configured with `stream: false` for non-streaming mode.
///
/// # Arguments
///
/// * `model` - Name of the model to download (e.g., "llama3.2:latest")
///
/// # Example
///
/// ```
/// use ollama_oxide::PullRequest;
///
/// let request = PullRequest::new("llama3.2:latest");
/// ```
pub fn new<M: Into<String>>(model: M) -> Self {
Self {
model: model.into(),
insecure: None,
stream: Some(false), // v0.1.0: non-streaming only
}
}
/// Allow downloading over insecure connections.
///
/// When set to `true`, the download will proceed without TLS verification.
/// Use with caution, only in trusted network environments.
///
/// # Arguments
///
/// * `insecure` - Whether to allow insecure connections
///
/// # Example
///
/// ```
/// use ollama_oxide::PullRequest;
///
/// let request = PullRequest::new("llama3.2:latest")
/// .with_insecure(true);
/// ```
pub fn with_insecure(mut self, insecure: bool) -> Self {
self.insecure = Some(insecure);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_creates_request_with_model() {
let request = PullRequest::new("llama3.2:latest");
assert_eq!(request.model, "llama3.2:latest");
assert_eq!(request.insecure, None);
}
#[test]
fn test_with_insecure_sets_flag() {
let request = PullRequest::new("llama3.2:latest").with_insecure(true);
assert_eq!(request.insecure, Some(true));
}
#[test]
fn test_serialization_minimal() {
let request = PullRequest::new("llama3.2:latest");
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["model"], "llama3.2:latest");
assert_eq!(json["stream"], false);
assert!(json.get("insecure").is_none());
}
#[test]
fn test_serialization_full() {
let request = PullRequest::new("llama3.2:latest").with_insecure(true);
let json = serde_json::to_value(&request).unwrap();
assert_eq!(json["model"], "llama3.2:latest");
assert_eq!(json["insecure"], true);
assert_eq!(json["stream"], false);
}
#[test]
fn test_deserialization() {
let json = r#"{"model": "llama3.2:latest", "insecure": false}"#;
let request: PullRequest = serde_json::from_str(json).unwrap();
assert_eq!(request.model, "llama3.2:latest");
assert_eq!(request.insecure, Some(false));
}
}