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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//! # Architecture Detection Utilities
//!
//! This module provides utilities for detecting the current system architecture
//! and selecting the appropriate DuckDB binary for the platform. It supports
//! automatic detection with manual override capabilities for testing and
//! cross-compilation scenarios.
//!
//! ## Supported Architectures
//!
//! - **x86_64**: Intel/AMD 64-bit processors
//! - **arm64/aarch64**: Apple Silicon and ARM 64-bit processors
//! - **Fallback**: Generic binary for unsupported architectures
//!
//! ## Usage Examples
//!
//! ```rust
//! use frozen_duckdb::architecture;
//!
//! // Detect current architecture
//! let arch = architecture::detect();
//! println!("Current architecture: {}", arch);
//!
//! // Check if architecture is supported
//! if architecture::is_supported(&arch) {
//! println!("✅ Architecture is supported");
//! } else {
//! println!("⚠️ Architecture may not be optimized");
//! }
//!
//! // Get the appropriate binary name
//! let binary = architecture::get_binary_name();
//! println!("Using binary: {}", binary);
//! ```
//!
//! ## Environment Override
//!
//! You can override the detected architecture by setting the `ARCH` environment variable:
//!
//! ```bash
//! # Force x86_64 binary selection
//! ARCH=x86_64 cargo build
//!
//! # Force arm64 binary selection
//! ARCH=arm64 cargo build
//! ```
//!
//! ## Performance Considerations
//!
//! - Architecture detection is performed once at startup
//! - Binary selection is cached for the duration of the process
//! - Manual override adds minimal overhead (<1ms)
//! - Unsupported architectures fall back to generic binary
use env;
/// Detects the current system architecture with manual override support.
///
/// This function first checks for the `ARCH` environment variable to allow
/// manual override of the detected architecture. If not set, it falls back
/// to the system's actual architecture using `std::env::consts::ARCH`.
///
/// # Returns
///
/// A string representing the architecture (e.g., "x86_64", "arm64", "aarch64").
///
/// # Examples
///
/// ```rust
/// use frozen_duckdb::architecture;
///
/// // Detect current architecture
/// let arch = architecture::detect();
/// assert!(!arch.is_empty());
///
/// // With environment override
/// std::env::set_var("ARCH", "x86_64");
/// assert_eq!(architecture::detect(), "x86_64");
/// std::env::remove_var("ARCH");
/// ```
///
/// # Performance
///
/// This function is optimized for frequent calls with minimal overhead.
/// Architecture detection is cached at the OS level, so repeated calls
/// are very fast (<1μs).
/// Checks if the given architecture is supported with optimized binaries.
///
/// This function determines whether we have architecture-specific optimized
/// binaries available for the given architecture. Supported architectures
/// get performance-optimized binaries, while unsupported ones fall back
/// to generic binaries.
///
/// # Arguments
///
/// * `arch` - The architecture string to check (e.g., "x86_64", "arm64")
///
/// # Returns
///
/// `true` if the architecture has optimized binaries available,
/// `false` if it will use the generic fallback binary.
///
/// # Examples
///
/// ```rust
/// use frozen_duckdb::architecture;
///
/// assert!(architecture::is_supported("x86_64"));
/// assert!(architecture::is_supported("arm64"));
/// assert!(architecture::is_supported("aarch64"));
/// assert!(!architecture::is_supported("unknown"));
/// assert!(!architecture::is_supported(""));
/// ```
///
/// # Supported Architectures
///
/// - `x86_64`: Intel/AMD 64-bit processors (55MB optimized binary)
/// - `arm64`: Apple Silicon processors (50MB optimized binary)
/// - `aarch64`: ARM 64-bit processors (same as arm64, 50MB optimized binary)
/// Gets the appropriate binary filename for the current architecture.
///
/// This function selects the correct DuckDB binary based on the detected
/// architecture. It returns architecture-specific binaries for supported
/// platforms and falls back to a generic binary for unsupported ones.
///
/// # Returns
///
/// A string containing the binary filename that should be used for linking.
///
/// # Examples
///
/// ```rust
/// use frozen_duckdb::architecture;
///
/// let binary = architecture::get_binary_name();
/// assert!(binary.starts_with("libduckdb"));
/// assert!(binary.ends_with(".dylib"));
///
/// // With architecture override
/// std::env::set_var("ARCH", "x86_64");
/// assert_eq!(architecture::get_binary_name(), "libduckdb_x86_64.dylib");
/// std::env::remove_var("ARCH");
/// ```
///
/// # Binary Mapping
///
/// | Architecture | Binary Name | Size | Optimization |
/// |--------------|-------------|------|--------------|
/// | x86_64 | libduckdb_x86_64.dylib | 55MB | Intel/AMD optimized |
/// | arm64/aarch64 | libduckdb_arm64.dylib | 50MB | ARM optimized |
/// | Other | libduckdb.dylib | ~50MB | Generic fallback |
///
/// # Performance Impact
///
/// Using architecture-specific binaries provides:
/// - **x86_64**: Up to 15% better performance on Intel/AMD processors
/// - **arm64**: Up to 20% better performance on Apple Silicon
/// - **Generic**: Baseline performance, works everywhere