static_web_server/
helpers.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// This file is part of Static Web Server.
3// See https://static-web-server.net/ for more information
4// Copyright (C) 2019-present Jose Quintana <joseluisq.net>
5
6use std::fs;
7use std::path::{Path, PathBuf};
8
9use crate::{Context, Result};
10
11/// Validate and return a directory path.
12pub fn get_valid_dirpath<P: AsRef<Path>>(path: P) -> Result<PathBuf>
13where
14    PathBuf: From<P>,
15{
16    match PathBuf::from(path) {
17        v if !v.exists() => bail!("path {} was not found or inaccessible", v.display()),
18        v if !v.is_dir() => bail!("path {} is not a valid directory", v.display()),
19        v => Ok(v),
20    }
21}
22
23/// Read the entire contents of a file into a bytes vector.
24pub fn read_bytes(path: &Path) -> Result<Vec<u8>> {
25    fs::read(path).with_context(|| format!("failed to read file `{}`", path.display()))
26}
27
28/// Read the entire contents of a file into a bytes vector or default to empty.
29pub fn read_bytes_default(path: &Path) -> Vec<u8> {
30    fs::read(path).unwrap_or_default()
31}
32
33/// Read an UTF-8 file from a specific path.
34pub fn read_file(path: &Path) -> Result<String> {
35    match String::from_utf8(read_bytes(path)?) {
36        Ok(s) => Ok(s),
37        Err(_) => bail!("path at `{}` was not valid utf-8", path.display()),
38    }
39}
40
41pub fn stringify(dst: &mut String, path: &serde_ignored::Path<'_>) {
42    use serde_ignored::Path;
43
44    match *path {
45        Path::Root => {}
46        Path::Seq { parent, index } => {
47            stringify(dst, parent);
48            if !dst.is_empty() {
49                dst.push('.');
50            }
51            dst.push_str(&index.to_string());
52        }
53        Path::Map { parent, ref key } => {
54            stringify(dst, parent);
55            if !dst.is_empty() {
56                dst.push('.');
57            }
58            dst.push_str(key);
59        }
60        Path::Some { parent }
61        | Path::NewtypeVariant { parent }
62        | Path::NewtypeStruct { parent } => stringify(dst, parent),
63    }
64}
65
66#[cfg(windows)]
67/// In Windows systems it adjusts the `PathBuf` stripping its `\\?\` prefix.
68pub fn adjust_canonicalization(p: &Path) -> String {
69    const VERBATIM_PREFIX: &str = r#"\\?\"#;
70    let p = p.to_str().unwrap_or_default();
71    let p = if p.starts_with(VERBATIM_PREFIX) {
72        p.strip_prefix(VERBATIM_PREFIX).unwrap_or_default()
73    } else {
74        p
75    };
76    p.to_owned()
77}