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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*!
# Serper SDK
A minimalistic yet ergonomic Rust SDK for the Serper Google Search API.
## Features
- **Type-safe API** with comprehensive error handling
- **Modular architecture** with clear separation of concerns
- **Async-first design** with concurrent request support
- **Flexible configuration** with environment variable support
- **Comprehensive testing** with extensive test coverage
## Quick Start
```rust
use serper_sdk::{SearchService, SearchQuery, SearchResponse};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a search service (with example API key for documentation)
let service = SearchService::new("demo-key-for-docs".to_string())?;
// Build a search query
let query = SearchQuery::new("Hamze Ghalebi CTO at Remolab".to_string())?
.with_location("Paris".to_string())
.with_page(1);
// Create a mock response for documentation example
let response = SearchResponse::new();
// Process results (in real usage, you'd use service.search(&query).await?)
println!("Query: {}", query.q);
println!("Location: {:?}", query.location);
println!("Results found: {}", response.organic_count());
Ok(())
}
```
## Architecture
The SDK is organized into several focused modules:
- **`core`**: Fundamental types and error handling
- **`search`**: Query construction and response parsing
- **`http`**: Transport layer and HTTP client functionality
- **`config`**: Configuration management
- **`utils`**: Common utilities and helpers
## Advanced Usage
### Custom Configuration
```rust
use serper_sdk::{SearchService, http::TransportConfig};
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create service with custom configuration
let transport_config = TransportConfig::default()
.with_timeout(Duration::from_secs(60));
let service = SearchService::with_config(
"demo-key-for-docs".to_string(),
"https://google.serper.dev".to_string(),
transport_config
)?;
println!("Service created with custom 60s timeout");
Ok(())
}
```
### Concurrent Searches
```rust
use serper_sdk::{SearchService, SearchQuery};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create service and queries
let _service = SearchService::new("demo-key-for-docs".to_string())?;
let queries = vec![
SearchQuery::new("Hamze Ghalebi CTO at Remolab".to_string())?,
SearchQuery::new("Hamze Ghalebi Remolab technology".to_string())?,
SearchQuery::new("Remolab France innovation".to_string())?,
];
// In real usage: let results = service.search_concurrent(&queries, Some(3)).await?;
println!("Prepared {} queries for concurrent execution", queries.len());
for (i, query) in queries.iter().enumerate() {
println!("Query {}: {}", i + 1, query.q);
}
Ok(())
}
```
### Query Builder Pattern
```rust
use serper_sdk::{SearchService, SearchQueryBuilder};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let _service = SearchService::new("demo-key-for-docs".to_string())?;
// Demonstrate the builder pattern
let query = SearchQueryBuilder::new()
.query("Hamze Ghalebi CTO at Remolab")
.location("Paris")
.country("fr")
.language("en")
.page(1)
.build()?;
println!("Built query: {}", query.q);
println!("Location: {:?}", query.location);
println!("Country: {:?}", query.gl);
println!("Language: {:?}", query.hl);
println!("Page: {:?}", query.page);
// In real usage: let response = service.search_with(|builder| { ... }).await?;
Ok(())
}
```
*/
// Core modules
// Re-export main types for convenience
pub use ;
pub use ;
pub use ;
// Legacy compatibility - re-export the main client for backward compatibility
pub use SearchService as SerperClient;