diff --git a/CHANGES.md b/CHANGES.md index ece389c43..4c02b0944 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -55,6 +55,10 @@ - <https://github.com/georust/gdal/pull/278> +- Deprecate `Transaction::dataset` and `Transaction::dataset_mut`. Add `Deref` and `DerefMut` implementations instead. + + - <https://github.com/georust/gdal/pull/265> + ## 0.12 - Bump Rust edition to 2021 diff --git a/src/dataset.rs b/src/dataset.rs index dbfe7e34f..7a83c7a65 100644 --- a/src/dataset.rs +++ b/src/dataset.rs @@ -4,6 +4,7 @@ use std::mem::MaybeUninit; use std::{ ffi::NulError, ffi::{CStr, CString}, + ops::{Deref, DerefMut}, path::Path, ptr, }; @@ -662,11 +663,11 @@ impl Dataset { /// For datasources which support transactions, this creates a transaction. /// - /// During the transaction, the dataset can be mutably borrowed using - /// [`Transaction::dataset_mut`] to make changes. All changes done after the start of the - /// transaction are applied to the datasource when [`commit`](Transaction::commit) is called. - /// They may be canceled by calling [`rollback`](Transaction::rollback) instead, or by dropping - /// the `Transaction` without calling `commit`. + /// Because the transaction implements `DerefMut`, it can be used in place of the original + /// `Dataset` to make modifications. All changes done after the start of the transaction are + /// applied to the datasource when [`commit`](Transaction::commit) is called. They may be + /// canceled by calling [`rollback`](Transaction::rollback) instead, or by dropping the + /// `Transaction` without calling `commit`. /// /// Depending on the driver, using a transaction can give a huge performance improvement when /// creating a lot of geometry at once. This is because the driver doesn't need to commit every @@ -702,7 +703,7 @@ impl Dataset { /// // Start the transaction. /// let mut txn = dataset.start_transaction()?; /// - /// let mut layer = txn.dataset_mut().create_layer(LayerOptions { + /// let mut layer = txn.create_layer(LayerOptions { /// name: "grid", /// ty: gdal_sys::OGRwkbGeometryType::wkbPoint, /// ..Default::default() @@ -909,8 +910,8 @@ impl Drop for Dataset { /// back. /// /// The transaction holds a mutable borrow on the `Dataset` that it was created from, so during the -/// lifetime of the transaction you will need to access the dataset through -/// [`Transaction::dataset`] or [`Transaction::dataset_mut`]. +/// lifetime of the transaction you will need to access the dataset by dereferencing the +/// `Transaction` through its [`Deref`] or [`DerefMut`] implementations. #[derive(Debug)] pub struct Transaction<'a> { dataset: &'a mut Dataset, @@ -926,11 +927,13 @@ impl<'a> Transaction<'a> { } /// Returns a reference to the dataset from which this `Transaction` was created. + #[deprecated = "Transaction now implements Deref<Target = Dataset>, so you can call Dataset methods on it directly. Use .deref() if you need a reference to the underlying Dataset."] pub fn dataset(&self) -> &Dataset { self.dataset } /// Returns a mutable reference to the dataset from which this `Transaction` was created. + #[deprecated = "Transaction now implements DerefMut<Target = Dataset>, so you can call Dataset methods on it directly. Use .deref_mut() if you need a mutable reference to the underlying Dataset."] pub fn dataset_mut(&mut self) -> &mut Dataset { self.dataset } @@ -968,6 +971,20 @@ impl<'a> Transaction<'a> { } } +impl<'a> Deref for Transaction<'a> { + type Target = Dataset; + + fn deref(&self) -> &Self::Target { + self.dataset + } +} + +impl<'a> DerefMut for Transaction<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.dataset + } +} + impl<'a> Drop for Transaction<'a> { fn drop(&mut self) { if self.rollback_on_drop { @@ -1159,8 +1176,8 @@ mod tests { let (_temp_path, mut ds) = open_gpkg_for_update(fixture!("poly.gpkg")); let orig_feature_count = ds.layer(0).unwrap().feature_count(); - let mut txn = ds.start_transaction().unwrap(); - let mut layer = txn.dataset_mut().layer(0).unwrap(); + let txn = ds.start_transaction().unwrap(); + let mut layer = txn.layer(0).unwrap(); layer.create_feature(polygon()).unwrap(); assert!(txn.commit().is_ok()); @@ -1172,8 +1189,8 @@ mod tests { let (_temp_path, mut ds) = open_gpkg_for_update(fixture!("poly.gpkg")); let orig_feature_count = ds.layer(0).unwrap().feature_count(); - let mut txn = ds.start_transaction().unwrap(); - let mut layer = txn.dataset_mut().layer(0).unwrap(); + let txn = ds.start_transaction().unwrap(); + let mut layer = txn.layer(0).unwrap(); layer.create_feature(polygon()).unwrap(); assert!(txn.rollback().is_ok()); @@ -1186,8 +1203,8 @@ mod tests { let orig_feature_count = ds.layer(0).unwrap().feature_count(); { - let mut txn = ds.start_transaction().unwrap(); - let mut layer = txn.dataset_mut().layer(0).unwrap(); + let txn = ds.start_transaction().unwrap(); + let mut layer = txn.layer(0).unwrap(); layer.create_feature(polygon()).unwrap(); } // txn is dropped here.