@@ -5,7 +5,7 @@ use std::ffi::CString;
55
66use pyo3:: exceptions:: { PyException , PyTypeError } ;
77use pyo3:: prelude:: * ;
8- use pyo3:: types:: PyDict ;
8+ use pyo3:: types:: { PyDict , PyString } ;
99use pyo3:: { create_exception, ffi, intern} ;
1010
1111use :: boreal:: compiler;
@@ -25,6 +25,7 @@ create_exception!(boreal, AddRuleError, PyException, "error when adding rules");
2525#[ pymodule]
2626fn boreal ( m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
2727 m. add_function ( wrap_pyfunction ! ( compile, m) ?) ?;
28+ m. add_function ( wrap_pyfunction ! ( available_modules, m) ?) ?;
2829
2930 m. add ( "AddRuleError" , m. py ( ) . get_type :: < AddRuleError > ( ) ) ?;
3031 m. add ( "ScanError" , m. py ( ) . get_type :: < scanner:: ScanError > ( ) ) ?;
@@ -56,17 +57,7 @@ fn compile(
5657 includes : bool ,
5758 error_on_warning : bool ,
5859) -> PyResult < scanner:: Scanner > {
59- let mut compiler = compiler:: CompilerBuilder :: new ( )
60- . add_module ( :: boreal:: module:: Console :: with_callback ( |log| {
61- // XXX: when targetting python 3.12 or above, this could be simplified
62- // by using the "%.*s" format, avoiding the CString conversion.
63- if let Ok ( cstr) = CString :: new ( log) {
64- // Safety: see <https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_FromFormat>
65- // for the format. A '%s" expects a c-string pointer, which has just been built.
66- unsafe { ffi:: PySys_FormatStdout ( c"%s\n " . as_ptr ( ) , cstr. as_ptr ( ) ) }
67- }
68- } ) )
69- . build ( ) ;
60+ let mut compiler = build_compiler ( ) ;
7061
7162 compiler. set_params (
7263 compiler:: CompilerParams :: default ( )
@@ -159,6 +150,28 @@ fn compile(
159150 Ok ( scanner:: Scanner :: new ( compiler. into_scanner ( ) , warnings) )
160151}
161152
153+ #[ pyfunction]
154+ fn available_modules ( py : Python < ' _ > ) -> Vec < Bound < ' _ , PyString > > {
155+ build_compiler ( )
156+ . available_modules ( )
157+ . map ( |s| PyString :: new ( py, s) )
158+ . collect ( )
159+ }
160+
161+ fn build_compiler ( ) -> compiler:: Compiler {
162+ compiler:: CompilerBuilder :: new ( )
163+ . add_module ( :: boreal:: module:: Console :: with_callback ( |log| {
164+ // XXX: when targetting python 3.12 or above, this could be simplified
165+ // by using the "%.*s" format, avoiding the CString conversion.
166+ if let Ok ( cstr) = CString :: new ( log) {
167+ // Safety: see <https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_FromFormat>
168+ // for the format. A '%s" expects a c-string pointer, which has just been built.
169+ unsafe { ffi:: PySys_FormatStdout ( c"%s\n " . as_ptr ( ) , cstr. as_ptr ( ) ) }
170+ }
171+ } ) )
172+ . build ( )
173+ }
174+
162175fn convert_compiler_error ( err : & compiler:: AddRuleError , input_name : & str , input : & str ) -> String {
163176 err. to_short_description ( input_name, input)
164177}
0 commit comments