tesseract_ocr_static/
vars.rs1use core::ffi::CStr;
2use std::fs::File;
3use std::io::BufRead;
4use std::io::BufReader;
5use std::path::Path;
6
7use crate::InvalidVariable;
8use crate::Tesseract;
9use crate::WriteFailed;
10
11impl Tesseract {
12 #[doc = include_str!("../variables.md")]
22 pub fn set_variable(&mut self, name: &CStr, value: &CStr) -> Result<(), InvalidVariable> {
23 let ret =
24 unsafe { c::TessBaseAPISetVariable(self.ptr.as_ptr(), name.as_ptr(), value.as_ptr()) };
25 if ret != 0 {
26 Err(InvalidVariable)
27 } else {
28 Ok(())
29 }
30 }
31
32 pub fn set_debug_variable(&mut self, name: &CStr, value: &CStr) -> Result<(), InvalidVariable> {
38 let ret = unsafe {
39 c::TessBaseAPISetDebugVariable(self.ptr.as_ptr(), name.as_ptr(), value.as_ptr())
40 };
41 if ret != 0 {
42 Err(InvalidVariable)
43 } else {
44 Ok(())
45 }
46 }
47
48 pub fn get_variable_i32(&self, name: &CStr) -> Option<i32> {
50 let mut value = 0;
51 let ret =
52 unsafe { c::TessBaseAPIGetIntVariable(self.ptr.as_ptr(), name.as_ptr(), &mut value) };
53 (ret != 0).then_some(value)
54 }
55
56 pub fn get_variable_bool(&self, name: &CStr) -> Option<bool> {
58 let mut value = 0;
59 let ret =
60 unsafe { c::TessBaseAPIGetBoolVariable(self.ptr.as_ptr(), name.as_ptr(), &mut value) };
61 (ret != 0).then_some(value != 0)
62 }
63
64 pub fn get_variable_f64(&self, name: &CStr) -> Option<f64> {
66 let mut value = 0.0;
67 let ret = unsafe {
68 c::TessBaseAPIGetDoubleVariable(self.ptr.as_ptr(), name.as_ptr(), &mut value)
69 };
70 (ret != 0).then_some(value)
71 }
72
73 pub fn get_variable_c_str<'a>(&'a self, name: &CStr) -> Option<&'a CStr> {
75 let ptr = unsafe { c::TessBaseAPIGetStringVariable(self.ptr.as_ptr(), name.as_ptr()) };
76 if ptr.is_null() {
77 return None;
78 }
79 Some(unsafe { CStr::from_ptr(ptr) })
80 }
81
82 pub fn read_config_file(&mut self, filename: &Path) -> std::io::Result<()> {
89 do_read_config_file(filename, |name, value| self.set_variable(name, value))
90 }
91
92 pub fn read_debug_config_file(&mut self, filename: &Path) -> std::io::Result<()> {
99 do_read_config_file(filename, |name, value| self.set_debug_variable(name, value))
100 }
101
102 pub fn print_variables_to_file(&self, filename: &CStr) -> Result<(), WriteFailed> {
104 let ret =
105 unsafe { c::TessBaseAPIPrintVariablesToFile(self.ptr.as_ptr(), filename.as_ptr()) };
106 if ret < 0 { Err(WriteFailed) } else { Ok(()) }
107 }
108}
109
110fn do_read_config_file(
111 filename: &Path,
112 mut set_variable: impl FnMut(&CStr, &CStr) -> Result<(), InvalidVariable>,
113) -> std::io::Result<()> {
114 use std::io::ErrorKind::InvalidData;
115 let file = BufReader::new(File::open(filename)?);
116 for line in file.lines() {
117 let mut line = line?.into_bytes();
118 line.push(0);
120 let mut line = line.as_mut_slice();
121 while let Some(ch) = line.first() {
123 if !ch.is_ascii_whitespace() {
124 break;
125 }
126 line = &mut line[1..];
127 }
128 match line.first() {
130 Some(&b'#') | None => continue,
131 _ => {}
132 }
133 let i = line
134 .iter()
135 .position(|ch| ch.is_ascii_whitespace())
136 .ok_or(InvalidData)?;
137 line[i] = 0;
139 let name = &line[..i];
140 let mut value = &line[i + 1..];
141 while let Some(ch) = value.first() {
143 if !ch.is_ascii_whitespace() {
144 break;
145 }
146 value = &value[1..];
147 }
148 let name = CStr::from_bytes_with_nul(name).map_err(|_| InvalidData)?;
149 let value = CStr::from_bytes_with_nul(value).map_err(|_| InvalidData)?;
150 set_variable(name, value).map_err(std::io::Error::other)?;
151 }
152 Ok(())
153}