@@ -90,6 +90,122 @@ fn optionals() -> Result<()> {
90
90
Ok ( ( ) )
91
91
}
92
92
93
+ #[ test]
94
+ fn read_optional ( ) -> Result < ( ) > {
95
+ let td = cap_tempfile:: tempdir ( cap_std:: ambient_authority ( ) ) ?;
96
+
97
+ // Test non-existent file returns None
98
+ assert ! ( td. read_optional( "nonexistent" ) ?. is_none( ) ) ;
99
+
100
+ // Test existing file with string contents
101
+ td. write ( "test.txt" , "hello world" ) ?;
102
+ let contents = td. read_optional ( "test.txt" ) ?;
103
+ assert ! ( contents. is_some( ) ) ;
104
+ assert_eq ! ( contents. unwrap( ) , b"hello world" ) ;
105
+
106
+ // Test existing file with binary contents
107
+ let binary_data = vec ! [ 0u8 , 1 , 2 , 254 , 255 ] ;
108
+ td. write ( "test.bin" , & binary_data) ?;
109
+ let contents = td. read_optional ( "test.bin" ) ?;
110
+ assert ! ( contents. is_some( ) ) ;
111
+ assert_eq ! ( contents. unwrap( ) , binary_data) ;
112
+
113
+ // Test empty file
114
+ td. write ( "empty.txt" , "" ) ?;
115
+ let contents = td. read_optional ( "empty.txt" ) ?;
116
+ assert ! ( contents. is_some( ) ) ;
117
+ assert_eq ! ( contents. unwrap( ) , b"" ) ;
118
+
119
+ // Test file in subdirectory
120
+ td. create_dir_all ( "sub/dir" ) ?;
121
+ td. write ( "sub/dir/file.txt" , "nested content" ) ?;
122
+ let contents = td. read_optional ( "sub/dir/file.txt" ) ?;
123
+ assert ! ( contents. is_some( ) ) ;
124
+ assert_eq ! ( contents. unwrap( ) , b"nested content" ) ;
125
+
126
+ // Test non-existent file in existing directory
127
+ assert ! ( td. read_optional( "sub/dir/missing.txt" ) ?. is_none( ) ) ;
128
+
129
+ // Test large file
130
+ let large_data = vec ! [ b'x' ; 10000 ] ;
131
+ td. write ( "large.txt" , & large_data) ?;
132
+ let contents = td. read_optional ( "large.txt" ) ?;
133
+ assert ! ( contents. is_some( ) ) ;
134
+ assert_eq ! ( contents. unwrap( ) , large_data) ;
135
+
136
+ #[ cfg( not( windows) ) ]
137
+ {
138
+ // Test symlink to existing file
139
+ td. symlink ( "test.txt" , "link_to_test" ) ?;
140
+ let contents = td. read_optional ( "link_to_test" ) ?;
141
+ assert ! ( contents. is_some( ) ) ;
142
+ assert_eq ! ( contents. unwrap( ) , b"hello world" ) ;
143
+
144
+ // Test broken symlink returns None (NotFound is mapped to None)
145
+ td. symlink ( "nonexistent_target" , "broken_link" ) ?;
146
+ assert ! ( td. read_optional( "broken_link" ) ?. is_none( ) ) ;
147
+ }
148
+
149
+ Ok ( ( ) )
150
+ }
151
+
152
+ #[ test]
153
+ fn read_to_string_optional ( ) -> Result < ( ) > {
154
+ let td = cap_tempfile:: tempdir ( cap_std:: ambient_authority ( ) ) ?;
155
+
156
+ // Test non-existent file returns None
157
+ assert ! ( td. read_to_string_optional( "nonexistent" ) ?. is_none( ) ) ;
158
+
159
+ // Test existing file with valid UTF-8 string
160
+ td. write ( "test.txt" , "hello world" ) ?;
161
+ let contents = td. read_to_string_optional ( "test.txt" ) ?;
162
+ assert ! ( contents. is_some( ) ) ;
163
+ assert_eq ! ( contents. unwrap( ) , "hello world" ) ;
164
+
165
+ // Test file with UTF-8 content including unicode
166
+ let unicode_content = "Hello 世界 🌍" ;
167
+ td. write ( "unicode.txt" , unicode_content) ?;
168
+ let contents = td. read_to_string_optional ( "unicode.txt" ) ?;
169
+ assert ! ( contents. is_some( ) ) ;
170
+ assert_eq ! ( contents. unwrap( ) , unicode_content) ;
171
+
172
+ // Test empty file
173
+ td. write ( "empty.txt" , "" ) ?;
174
+ let contents = td. read_to_string_optional ( "empty.txt" ) ?;
175
+ assert ! ( contents. is_some( ) ) ;
176
+ assert_eq ! ( contents. unwrap( ) , "" ) ;
177
+
178
+ // Test file in subdirectory
179
+ td. create_dir_all ( "sub/dir" ) ?;
180
+ td. write ( "sub/dir/file.txt" , "nested content" ) ?;
181
+ let contents = td. read_to_string_optional ( "sub/dir/file.txt" ) ?;
182
+ assert ! ( contents. is_some( ) ) ;
183
+ assert_eq ! ( contents. unwrap( ) , "nested content" ) ;
184
+
185
+ // Test non-existent file in existing directory
186
+ assert ! ( td. read_to_string_optional( "sub/dir/missing.txt" ) ?. is_none( ) ) ;
187
+
188
+ // Test file with invalid UTF-8 should return an error
189
+ let invalid_utf8 = vec ! [ 0xff , 0xfe , 0xfd ] ;
190
+ td. write ( "invalid.bin" , invalid_utf8. as_slice ( ) ) ?;
191
+ assert ! ( td. read_to_string_optional( "invalid.bin" ) . is_err( ) ) ;
192
+
193
+ #[ cfg( not( windows) ) ]
194
+ {
195
+ // Test symlink to existing file
196
+ td. symlink ( "test.txt" , "link_to_test" ) ?;
197
+ let contents = td. read_to_string_optional ( "link_to_test" ) ?;
198
+ assert ! ( contents. is_some( ) ) ;
199
+ assert_eq ! ( contents. unwrap( ) , "hello world" ) ;
200
+
201
+ // Test broken symlink returns None (NotFound is mapped to None)
202
+ td. symlink ( "nonexistent_target" , "broken_link" ) ?;
203
+ assert ! ( td. read_to_string_optional( "broken_link" ) ?. is_none( ) ) ;
204
+ }
205
+
206
+ Ok ( ( ) )
207
+ }
208
+
93
209
#[ test]
94
210
fn ensuredir ( ) -> Result < ( ) > {
95
211
let td = cap_tempfile:: tempdir ( cap_std:: ambient_authority ( ) ) ?;
0 commit comments