@@ -109,6 +109,10 @@ pub use math::Vec3;
109
109
#[ cfg( feature = "cgmath" ) ]
110
110
pub type Vec3 = cgmath:: Vector3 < f32 > ;
111
111
112
+ pub mod error;
113
+
114
+ pub use error:: { Error , ParseError , ResolveError } ;
115
+
112
116
// LDraw File Format Specification
113
117
// https://www.ldraw.org/article/218.html
114
118
@@ -603,15 +607,15 @@ named!(
603
607
/// Vec3{ x: 1.0, y: 1.0, z: 1.0 }
604
608
/// ]
605
609
/// });
606
- /// assert_eq!(parse_raw(b"0 this is a comment\n2 16 0 0 0 1 1 1"), vec![cmd0, cmd1]);
610
+ /// assert_eq!(parse_raw(b"0 this is a comment\n2 16 0 0 0 1 1 1").unwrap() , vec![cmd0, cmd1]);
607
611
/// }
608
612
/// ```
609
- pub fn parse_raw ( ldr_content : & [ u8 ] ) -> Vec < CommandType > {
613
+ pub fn parse_raw ( ldr_content : & [ u8 ] ) -> Result < Vec < CommandType > , Error > {
610
614
// "An LDraw file consists of one command per line."
611
- match many0 ( read_line) ( ldr_content) {
612
- Ok ( ( _ , cmds ) ) => cmds ,
613
- Err ( _ ) => panic ! ( "TODO - Error handling" ) ,
614
- }
615
+ many0 ( read_line) ( ldr_content) . map_or_else (
616
+ |e| Err ( Error :: Parse ( ParseError :: new_from_nom ( "" , & e ) ) ) ,
617
+ | ( _ , cmds ) | Ok ( cmds ) ,
618
+ )
615
619
}
616
620
617
621
struct QueuedFileRef {
@@ -710,17 +714,20 @@ fn resolve_file_refs(
710
714
}
711
715
}
712
716
713
- fn load_and_parse_single_file ( filename : & str , resolver : & dyn FileRefResolver ) -> SourceFile {
717
+ fn load_and_parse_single_file (
718
+ filename : & str ,
719
+ resolver : & dyn FileRefResolver ,
720
+ ) -> Result < SourceFile , Error > {
714
721
//match resolver.resolve(filename) {}
715
- let raw_content = resolver. resolve ( filename) ;
722
+ let raw_content = resolver. resolve ( filename) ? ;
716
723
let mut source_file = SourceFile {
717
724
filename : filename. to_string ( ) ,
718
725
raw_content,
719
726
cmds : Vec :: new ( ) ,
720
727
} ;
721
- let cmds = parse_raw ( & source_file. raw_content [ ..] ) ;
728
+ let cmds = parse_raw ( & source_file. raw_content [ ..] ) ? ;
722
729
source_file. cmds = cmds;
723
- source_file
730
+ Ok ( source_file)
724
731
}
725
732
726
733
/// Parse a single file and its sub-file references recursively.
@@ -731,35 +738,36 @@ fn load_and_parse_single_file(filename: &str, resolver: &dyn FileRefResolver) ->
731
738
/// up populating the given `source_map`, which can be pre-populated manually or from a
732
739
/// previous call with already loaded and parsed files.
733
740
/// ```rust
734
- /// use weldr::{ FileRefResolver, parse };
741
+ /// use weldr::{ FileRefResolver, parse, ResolveError };
735
742
/// use std::collections::HashMap;
736
743
///
737
744
/// struct MyCustomResolver {};
738
745
///
739
746
/// impl FileRefResolver for MyCustomResolver {
740
- /// fn resolve(&self, filename: &str) -> Vec<u8> {
741
- /// vec![] // replace with custom impl
747
+ /// fn resolve(&self, filename: &str) -> Result< Vec<u8>, ResolveError > {
748
+ /// Ok( vec![]) // replace with custom impl
742
749
/// }
743
750
/// }
744
751
///
745
- /// fn main() {
752
+ /// fn main() -> Result<(), Box<dyn std::error::Error>> {
746
753
/// let resolver = MyCustomResolver{};
747
754
/// let mut source_map = HashMap::new();
748
- /// let root_file = parse("root.ldr", &resolver, &mut source_map);
755
+ /// let root_file = parse("root.ldr", &resolver, &mut source_map)? ;
749
756
/// assert_eq!(root_file.borrow().filename, "root.ldr");
757
+ /// Ok(())
750
758
/// }
751
759
/// ```
752
760
pub fn parse (
753
761
filename : & str ,
754
762
resolver : & dyn FileRefResolver ,
755
763
source_map : & mut HashMap < String , Rc < RefCell < SourceFile > > > ,
756
- ) -> Rc < RefCell < SourceFile > > {
764
+ ) -> Result < Rc < RefCell < SourceFile > > , Error > {
757
765
if let Some ( existing_file) = source_map. get ( filename) {
758
- return Rc :: clone ( existing_file) ;
766
+ return Ok ( Rc :: clone ( existing_file) ) ;
759
767
}
760
768
let mut queue = ResolveQueue :: new ( ) ;
761
769
println ! ( "Loading root file: {}" , filename) ;
762
- let root_file = load_and_parse_single_file ( filename, resolver) ;
770
+ let root_file = load_and_parse_single_file ( filename, resolver) ? ;
763
771
let root_file = Rc :: new ( RefCell :: new ( root_file) ) ;
764
772
{
765
773
println ! (
@@ -777,7 +785,7 @@ pub fn parse(
777
785
println ! ( "Already parsed; reusing sub-file: {}" , filename) ;
778
786
} else {
779
787
println ! ( "Not yet parsed; parsing sub-file: {}" , filename) ;
780
- let source_file = load_and_parse_single_file ( & filename[ ..] , resolver) ;
788
+ let source_file = load_and_parse_single_file ( & filename[ ..] , resolver) ? ;
781
789
let subfile = Rc :: new ( RefCell :: new ( source_file) ) ;
782
790
println ! (
783
791
"Post-loading resolving subfile refs of sub-file: {}" ,
@@ -796,7 +804,7 @@ pub fn parse(
796
804
resolve_file_refs ( queued_file. 0 . referer , & mut queue, source_map) ;
797
805
}
798
806
}
799
- root_file
807
+ Ok ( root_file)
800
808
}
801
809
802
810
/// [Line Type 0](https://www.ldraw.org/article/218.html#lt0) META command:
@@ -1029,7 +1037,7 @@ pub trait FileRefResolver {
1029
1037
/// Unix style `\n` or Windows style `\r\n`.
1030
1038
///
1031
1039
/// See [`parse`] for usage.
1032
- fn resolve ( & self , filename : & str ) -> Vec < u8 > ;
1040
+ fn resolve ( & self , filename : & str ) -> Result < Vec < u8 > , ResolveError > ;
1033
1041
}
1034
1042
1035
1043
#[ cfg( test) ]
@@ -1980,7 +1988,7 @@ mod tests {
1980
1988
] ,
1981
1989
} ) ;
1982
1990
assert_eq ! (
1983
- parse_raw( b"0 this is a comment\n 2 16 0 0 0 1 1 1" ) ,
1991
+ parse_raw( b"0 this is a comment\n 2 16 0 0 0 1 1 1" ) . unwrap ( ) ,
1984
1992
vec![ cmd0, cmd1]
1985
1993
) ;
1986
1994
@@ -2012,7 +2020,8 @@ mod tests {
2012
2020
file : SubFileRef :: UnresolvedRef ( "aa/aaaaddd" . to_string ( ) ) ,
2013
2021
} ) ;
2014
2022
assert_eq ! (
2015
- parse_raw( b"\n 0 this doesn't matter\n \n 1 16 0 0 0 1 0 0 0 1 0 0 0 1 aa/aaaaddd" ) ,
2023
+ parse_raw( b"\n 0 this doesn't matter\n \n 1 16 0 0 0 1 0 0 0 1 0 0 0 1 aa/aaaaddd" )
2024
+ . unwrap( ) ,
2016
2025
vec![ cmd0, cmd1]
2017
2026
) ;
2018
2027
@@ -2046,7 +2055,8 @@ mod tests {
2046
2055
assert_eq ! (
2047
2056
parse_raw(
2048
2057
b"\r \n 0 this doesn't \" matter\" \r \n \r \n 1 16 0 0 0 1 0 0 0 1 0 0 0 1 aa/aaaaddd\n "
2049
- ) ,
2058
+ )
2059
+ . unwrap( ) ,
2050
2060
vec![ cmd0, cmd1]
2051
2061
) ;
2052
2062
@@ -2101,7 +2111,8 @@ mod tests {
2101
2111
assert_eq ! (
2102
2112
parse_raw(
2103
2113
b"1 16 0 0 0 1 0 0 0 1 0 0 0 1 aa/aaaaddd\n 1 16 0 0 0 1 0 0 0 1 0 0 0 1 aa/aaaaddd"
2104
- ) ,
2114
+ )
2115
+ . unwrap( ) ,
2105
2116
vec![ cmd0, cmd1]
2106
2117
) ;
2107
2118
}
0 commit comments