Skip to main content

harmos_runtime/filesystem/
input.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10// Bounded reads of regular input files
11
12/* === Modules === */
13
14/* === Re-Exports === */
15
16/* === Imports === */
17
18// Standard Library Imports
19use std::{
20    io::{self, Read},
21    path::Path,
22};
23
24// Third Party Imports
25
26// Local Imports
27
28/* === Constants === */
29
30/* === Macros === */
31
32/* === Type Aliases === */
33
34/* === Structs === */
35
36/* === Enums === */
37
38/* === Traits === */
39
40/* === Implementations === */
41
42/* === Public Functions === */
43
44pub fn read(path: &Path, limit: usize) -> io::Result<Vec<u8>> {
45    let maximum = u64::try_from(limit)
46        .ok()
47        .and_then(|value| value.checked_add(1))
48        .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "input file limit is too large"))?;
49    if !std::fs::metadata(path)?.is_file() {
50        return Err(io::Error::new(io::ErrorKind::InvalidInput, "input must be a regular file"));
51    }
52    let file = std::fs::File::open(path)?;
53    if !file.metadata()?.is_file() {
54        return Err(io::Error::new(io::ErrorKind::InvalidInput, "input must be a regular file"));
55    }
56    let mut bytes = Vec::new();
57    file.take(maximum).read_to_end(&mut bytes)?;
58    if bytes.len() > limit {
59        return Err(io::Error::new(io::ErrorKind::InvalidInput, format!("input file exceeds {limit} bytes")));
60    }
61    Ok(bytes)
62}
63
64/* === Private Functions === */
65
66/* === Tests === */