]> git.proxmox.com Git - rustc.git/blob - vendor/gix-worktree/src/read.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / vendor / gix-worktree / src / read.rs
1 //! This module allows creating git blobs from worktree files.
2 //!
3 //! For the most part a blob just contains the raw on-disk data. However symlinks need to be considered properly
4 //! and attributes/config options need to be considered.
5
6 use std::{
7 fs::{read_link, File},
8 io::{self, Read},
9 path::Path,
10 };
11
12 use gix_object::Blob;
13 use gix_path as path;
14
15 // TODO: tests
16
17 // TODO: what to do about precompose unicode and ignore_case for symlinks
18
19 /// Create a blob from a file or symlink.
20 pub fn blob(path: &Path, capabilities: &gix_fs::Capabilities) -> io::Result<Blob> {
21 let mut data = Vec::new();
22 data_to_buf(path, &mut data, capabilities)?;
23 Ok(Blob { data })
24 }
25
26 /// Create a blob from a file or symlink.
27 pub fn blob_with_meta(path: &Path, is_symlink: bool, capabilities: &gix_fs::Capabilities) -> io::Result<Blob> {
28 let mut data = Vec::new();
29 data_to_buf_with_meta(path, &mut data, is_symlink, capabilities)?;
30 Ok(Blob { data })
31 }
32
33 /// Create blob data from a file or symlink.
34 pub fn data_to_buf<'a>(path: &Path, buf: &'a mut Vec<u8>, capabilities: &gix_fs::Capabilities) -> io::Result<&'a [u8]> {
35 data_to_buf_with_meta(path, buf, path.symlink_metadata()?.is_symlink(), capabilities)
36 }
37
38 /// Create a blob from a file or symlink.
39 pub fn data_to_buf_with_meta<'a>(
40 path: &Path,
41 buf: &'a mut Vec<u8>,
42 is_symlink: bool,
43 capabilities: &gix_fs::Capabilities,
44 ) -> io::Result<&'a [u8]> {
45 buf.clear();
46 // symlinks are only stored as actual symlinks if the FS supports it otherwise they are just
47 // normal files with their content equal to the linked path (so can be read normally)
48 //
49 if is_symlink && capabilities.symlink {
50 // conversion to bstr can never fail because symlinks are only used
51 // on unix (by git) so no reason to use the try version here
52 let symlink_path = path::into_bstr(read_link(path)?);
53 buf.extend_from_slice(&symlink_path);
54 // TODO: there is no reason this should be a clone
55 // std isn't great about allowing users to avoid allocations but we could
56 // simply write our own wrapper around libc::readlink which reuses the
57 // buffer. This would require unsafe code tough (obviously)
58 } else {
59 buf.clear();
60 File::open(path)?.read_to_end(buf)?;
61 // TODO apply filters
62 }
63 Ok(buf.as_slice())
64 }