@@ -13,123 +13,128 @@ use pyo3::create_exception;
1313create_exception ! ( rustfluent, ParserError , pyo3:: exceptions:: PyException ) ;
1414
1515#[ pymodule]
16- fn rustfluent ( m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
17- m. add_class :: < Bundle > ( ) ?;
18- m. add ( "ParserError" , m. py ( ) . get_type :: < ParserError > ( ) ) ?;
19- Ok ( ( ) )
20- }
16+ mod rustfluent {
17+ use super :: * ;
2118
22- #[ pyclass]
23- struct Bundle {
24- bundle : FluentBundle < FluentResource > ,
25- }
19+ #[ pymodule_export]
20+ use super :: ParserError ;
2621
27- #[ pymethods]
28- impl Bundle {
29- #[ new]
30- #[ pyo3( signature = ( language, ftl_filenames, strict=false ) ) ]
31- fn new ( language : & str , ftl_filenames : & ' _ Bound < ' _ , PyList > , strict : bool ) -> PyResult < Self > {
32- let langid: LanguageIdentifier = language. parse ( ) . expect ( "Parsing failed" ) ;
33- let mut bundle = FluentBundle :: new_concurrent ( vec ! [ langid] ) ;
22+ #[ pyclass]
23+ struct Bundle {
24+ bundle : FluentBundle < FluentResource > ,
25+ }
3426
35- for file_path in ftl_filenames. iter ( ) {
36- let path_string = file_path. to_string ( ) ;
37- let contents = fs:: read_to_string ( path_string)
38- . map_err ( |_| PyFileNotFoundError :: new_err ( file_path. to_string ( ) ) ) ?;
27+ #[ pymethods]
28+ impl Bundle {
29+ #[ new]
30+ #[ pyo3( signature = ( language, ftl_filenames, strict=false ) ) ]
31+ fn new (
32+ language : & str ,
33+ ftl_filenames : & ' _ Bound < ' _ , PyList > ,
34+ strict : bool ,
35+ ) -> PyResult < Self > {
36+ let langid: LanguageIdentifier = language. parse ( ) . expect ( "Parsing failed" ) ;
37+ let mut bundle = FluentBundle :: new_concurrent ( vec ! [ langid] ) ;
3938
40- let resource = match FluentResource :: try_new ( contents) {
41- Ok ( resource) => resource,
42- Err ( _) if strict => {
43- return Err ( ParserError :: new_err ( format ! (
44- "Error when parsing {file_path}."
45- ) ) ) ;
46- }
47- Err ( error) => {
48- // The first element of the error is the parsed resource, minus any
49- // invalid messages.
50- error. 0
51- }
52- } ;
53- bundle. add_resource_overriding ( resource) ;
54- }
39+ for file_path in ftl_filenames. iter ( ) {
40+ let path_string = file_path. to_string ( ) ;
41+ let contents = fs:: read_to_string ( path_string)
42+ . map_err ( |_| PyFileNotFoundError :: new_err ( file_path. to_string ( ) ) ) ?;
5543
56- Ok ( Self { bundle } )
57- }
44+ let resource = match FluentResource :: try_new ( contents) {
45+ Ok ( resource) => resource,
46+ Err ( _) if strict => {
47+ return Err ( ParserError :: new_err ( format ! (
48+ "Error when parsing {file_path}."
49+ ) ) ) ;
50+ }
51+ Err ( error) => {
52+ // The first element of the error is the parsed resource, minus any
53+ // invalid messages.
54+ error. 0
55+ }
56+ } ;
57+ bundle. add_resource_overriding ( resource) ;
58+ }
5859
59- #[ pyo3( signature = ( identifier, variables=None , use_isolating=true ) ) ]
60- pub fn get_translation (
61- & mut self ,
62- identifier : & str ,
63- variables : Option < & Bound < ' _ , PyDict > > ,
64- use_isolating : bool ,
65- ) -> PyResult < String > {
66- self . bundle . set_use_isolating ( use_isolating) ;
60+ Ok ( Self { bundle } )
61+ }
6762
68- let msg = self
69- . bundle
70- . get_message ( identifier)
71- . ok_or_else ( || ( PyValueError :: new_err ( format ! ( "{identifier} not found" ) ) ) ) ?;
63+ #[ pyo3( signature = ( identifier, variables=None , use_isolating=true ) ) ]
64+ pub fn get_translation (
65+ & mut self ,
66+ identifier : & str ,
67+ variables : Option < & Bound < ' _ , PyDict > > ,
68+ use_isolating : bool ,
69+ ) -> PyResult < String > {
70+ self . bundle . set_use_isolating ( use_isolating) ;
7271
73- let mut errors = vec ! [ ] ;
74- let pattern = msg . value ( ) . ok_or_else ( || {
75- PyValueError :: new_err ( format ! ( "{identifier} - Message has no value." , ) )
76- } ) ?;
72+ let msg = self
73+ . bundle
74+ . get_message ( identifier )
75+ . ok_or_else ( || ( PyValueError :: new_err ( format ! ( "{identifier} not found" ) ) ) ) ?;
7776
78- let mut args = FluentArgs :: new ( ) ;
77+ let mut errors = vec ! [ ] ;
78+ let pattern = msg. value ( ) . ok_or_else ( || {
79+ PyValueError :: new_err ( format ! ( "{identifier} - Message has no value." , ) )
80+ } ) ?;
7981
80- if let Some ( variables) = variables {
81- for variable in variables {
82- // Make sure the variable key is a Python string,
83- // raising a TypeError if not.
84- let python_key = variable. 0 ;
85- if !python_key. is_instance_of :: < PyString > ( ) {
86- return Err ( PyTypeError :: new_err ( format ! (
87- "Variable key not a str, got {python_key}."
88- ) ) ) ;
89- }
90- let key = python_key. to_string ( ) ;
91- // Set the variable value as a string or integer,
92- // raising a TypeError if not.
93- let python_value = variable. 1 ;
94- if python_value. is_instance_of :: < PyString > ( ) {
95- args. set ( key, python_value. to_string ( ) ) ;
96- } else if python_value. is_instance_of :: < PyInt > ( ) {
97- match python_value. extract :: < i32 > ( ) {
98- Ok ( int_value) => {
99- args. set ( key, int_value) ;
100- }
101- _ => {
102- // The Python integer overflowed i32.
103- // Fall back to displaying the variable key as its value.
104- let fallback_value = key. clone ( ) ;
105- args. set ( key, fallback_value) ;
106- }
82+ let mut args = FluentArgs :: new ( ) ;
83+
84+ if let Some ( variables) = variables {
85+ for variable in variables {
86+ // Make sure the variable key is a Python string,
87+ // raising a TypeError if not.
88+ let python_key = variable. 0 ;
89+ if !python_key. is_instance_of :: < PyString > ( ) {
90+ return Err ( PyTypeError :: new_err ( format ! (
91+ "Variable key not a str, got {python_key}."
92+ ) ) ) ;
10793 }
108- } else if python_value. is_instance_of :: < PyDate > ( ) {
109- // Display the Python date as YYYY-MM-DD.
110- match python_value. extract :: < NaiveDate > ( ) {
111- Ok ( chrono_date) => {
112- args. set ( key, chrono_date. format ( "%Y-%m-%d" ) . to_string ( ) ) ;
94+ let key = python_key. to_string ( ) ;
95+ // Set the variable value as a string or integer,
96+ // raising a TypeError if not.
97+ let python_value = variable. 1 ;
98+ if python_value. is_instance_of :: < PyString > ( ) {
99+ args. set ( key, python_value. to_string ( ) ) ;
100+ } else if python_value. is_instance_of :: < PyInt > ( ) {
101+ match python_value. extract :: < i32 > ( ) {
102+ Ok ( int_value) => {
103+ args. set ( key, int_value) ;
104+ }
105+ _ => {
106+ // The Python integer overflowed i32.
107+ // Fall back to displaying the variable key as its value.
108+ let fallback_value = key. clone ( ) ;
109+ args. set ( key, fallback_value) ;
110+ }
113111 }
114- _ => {
115- // Could not convert.
116- // Fall back to displaying the variable key as its value.
117- let fallback_value = key. clone ( ) ;
118- args. set ( key, fallback_value) ;
112+ } else if python_value. is_instance_of :: < PyDate > ( ) {
113+ // Display the Python date as YYYY-MM-DD.
114+ match python_value. extract :: < NaiveDate > ( ) {
115+ Ok ( chrono_date) => {
116+ args. set ( key, chrono_date. format ( "%Y-%m-%d" ) . to_string ( ) ) ;
117+ }
118+ _ => {
119+ // Could not convert.
120+ // Fall back to displaying the variable key as its value.
121+ let fallback_value = key. clone ( ) ;
122+ args. set ( key, fallback_value) ;
123+ }
119124 }
125+ } else {
126+ // The variable value was of an unsupported type.
127+ // Fall back to displaying the variable key as its value.
128+ let fallback_value = key. clone ( ) ;
129+ args. set ( key, fallback_value) ;
120130 }
121- } else {
122- // The variable value was of an unsupported type.
123- // Fall back to displaying the variable key as its value.
124- let fallback_value = key. clone ( ) ;
125- args. set ( key, fallback_value) ;
126131 }
127132 }
128- }
129133
130- let value = self
131- . bundle
132- . format_pattern ( pattern, Some ( & args) , & mut errors) ;
133- Ok ( value. to_string ( ) )
134+ let value = self
135+ . bundle
136+ . format_pattern ( pattern, Some ( & args) , & mut errors) ;
137+ Ok ( value. to_string ( ) )
138+ }
134139 }
135140}
0 commit comments