diff --git a/src/file.rs b/src/file.rs index 5d310ed..9e16f26 100644 --- a/src/file.rs +++ b/src/file.rs @@ -55,6 +55,10 @@ impl std::ops::DerefMut for File { impl File { #[allow(clippy::doc_markdown)] /// Open a netCDF file in read only mode. + /// + /// Consider using [`crate::open`] instead to open with + /// a generic `Path` object, and ensure read-only on + /// the `File` pub fn open(path: &path::Path) -> error::Result { let f = CString::new(path.to_str().unwrap()).unwrap(); let mut ncid: nc_type = -1; @@ -126,6 +130,37 @@ impl File { } } +/// File that does not allow writing to it, enforced by +/// borrow rules (can not get `mut File`) +/// +/// `Deref`s to `File`, but does not provide mutable access, +/// so the following code will not compile: +/// ```compile_fail +/// # fn main() -> netcdf::Result<()>{ +/// let file = netcdf::open("file.nc")?; +/// file.add_dimension("somedim", 10)?; +/// # } +/// ``` +#[derive(Debug)] +pub struct ReadOnlyFile { + file: File, +} + +impl std::ops::Deref for ReadOnlyFile { + type Target = File; + fn deref(&self) -> &Self::Target { + &self.file + } +} + +impl ReadOnlyFile { + pub(crate) fn open(path: &path::Path) -> error::Result { + Ok(Self { + file: File::open(path)? + }) + } +} + #[cfg(feature = "memory")] /// The memory mapped file is kept in this structure to keep the /// lifetime of the buffer longer than the file. diff --git a/src/lib.rs b/src/lib.rs index 932e301..d0b1cb2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,11 +100,11 @@ where } /// Open a netcdf file in read mode -pub fn open

(name: P) -> error::Result +pub fn open

(name: P) -> error::Result where P: AsRef, { - File::open(name.as_ref()) + ReadOnlyFile::open(name.as_ref()) } #[cfg(feature = "memory")] diff --git a/tests/lib.rs b/tests/lib.rs index 4a03295..7e974c8 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1591,8 +1591,8 @@ fn set_get_endian() { { // re-open it // and get "some variable" endian_value - let mut file_o = netcdf::open(&f).unwrap(); - let var = &mut file_o.root_mut().variable("some_variable").unwrap(); + let file_o = netcdf::open(&f).unwrap(); + let var = &file_o.variable("some_variable").unwrap(); assert_eq!(var.endian_value(), Ok(*i)); // close it (done when `file_a` goes out of scope) }