circle_of_confusion/
lib.rs1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4mod calculator;
5mod datamodel {
6 include!(concat!(env!("OUT_DIR"), "/circle_of_confusion.rs"));
7}
8
9pub use crate::datamodel::*;
10
11#[cfg(feature = "wasm-bindings")]
12mod wasm {
13 const PTR_OFFSET: usize = 1;
15
16 use crate::ffi_result::ResultValue;
17
18 use super::*;
19 use prost::Message;
20
21 fn get_result_protobuf() -> Result<(&'static mut [u8], FfiResult), usize> {
22 let ptr = (get_calculator_size() + PTR_OFFSET) as *mut u8;
23 let len = get_result_size();
24 let result_buffer = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
25 let current_result = FfiResult::default();
26 Ok((result_buffer, current_result))
27 }
28
29 #[unsafe(no_mangle)]
30 pub extern "C" fn get_settings_size() -> usize {
32 size_of::<Settings>()
33 + size_of::<CameraData>()
34 + size_of::<Filmback>()
35 + size_of::<Resolution>()
36 + size_of::<WorldUnit>()
37 + size_of::<Math>()
38 }
39
40 #[unsafe(no_mangle)]
41 pub extern "C" fn get_calculator_size() -> usize {
43 size_of::<Calculator>() + size_of::<DepthOfField>() + get_settings_size()
44 }
45
46 #[unsafe(no_mangle)]
47 pub extern "C" fn get_result_size() -> usize {
49 size_of::<FfiResult>()
50 }
51
52 unsafe fn initialize_calculator_inner(
54 settings_size: usize,
55 ) -> Result<Calculator, FfiError> {
56 let address = PTR_OFFSET as *mut u8;
57 let settings = unsafe {
58 let data = core::slice::from_raw_parts(address, settings_size);
59 Settings::decode(data)
60 }
61 .map_err(|_| FfiError::ProtoDecode)?;
62
63 let calculator = Calculator::new(settings);
64 let max_calculator_size = get_calculator_size();
65 calculator
66 .encode(&mut unsafe { core::slice::from_raw_parts_mut(address, max_calculator_size) })
67 .map_err(|_| FfiError::ProtoEncode)?;
68
69 Ok(calculator)
70 }
71
72 #[unsafe(no_mangle)]
73 pub extern "C" fn initialize_calculator(settings_size: usize) -> usize {
74 let (mut result_buffer, mut current_result) = match get_result_protobuf() {
75 Ok(value) => value,
76 Err(_) => return 0,
77 };
78
79 match unsafe { initialize_calculator_inner(settings_size) } {
80 Ok(calculator) => {
81 current_result.result_value =
82 Some(ResultValue::UintValue(calculator.encoded_len() as u32))
83 }
84 Err(error) => {
85 current_result.result_value = Some(ResultValue::Error(error.into()));
86 }
87 }
88 let _ = current_result.encode(&mut result_buffer);
89 current_result.encoded_len()
90 }
91
92 #[allow(invalid_null_arguments)]
93 unsafe fn calculate_inner(calculator_size: usize, value: f32) -> Result<f32, FfiError> {
94 let ptr = PTR_OFFSET as *const u8;
95
96 let current_calculator = unsafe {
97 let data = core::slice::from_raw_parts(ptr, calculator_size);
98 Calculator::decode(data)
99 }
100 .map_err(|_| FfiError::ProtoDecode)?;
101
102 Ok(current_calculator.calculate(value))
103 }
104
105 #[unsafe(no_mangle)]
106 pub fn calculate(value: f32, calculator_size: usize) -> usize {
107 let (mut result_buffer, mut current_result) = match get_result_protobuf() {
108 Ok(value) => value,
109 Err(value) => return value,
110 };
111 match unsafe { calculate_inner(calculator_size, value) } {
112 Ok(value) => current_result.result_value = Some(ResultValue::FloatValue(value)),
113 Err(error) => current_result.result_value = Some(ResultValue::Error(error.into())),
114 };
115
116 let _ = current_result.encode(&mut result_buffer);
117 current_result.encoded_len()
118 }
119}
120
121#[cfg(feature = "wasm-bindings")]
122pub use wasm::*;
123
124#[cfg(not(feature = "wasm-bindings"))]
125pub fn initialize_calculator(settings: Settings) -> Calculator {
126 Calculator::new(settings)
127}
128
129#[cfg(not(feature = "wasm-bindings"))]
130pub fn calculate(calculator: &Calculator, value: f32) -> f32 {
131 calculator.calculate(value)
132}