use bstr::{BStr, BString, ByteSlice}; use crate::{ blob::{DiffLineStats, ResourceKind}, tree,}; /// Represents any possible change in order to turn one tree into another, which references data owned by its producer.#[derive(Debug, Clone, Copy, PartialEq)]pub enum ChangeRef<'a> { /// An entry was added, like the addition of a file or directory. Addition { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: &'a BStr, /// The mode of the added entry. entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The object id of the added entry. id: gix_hash::ObjectId, }, /// An entry was deleted, like the deletion of a file or directory. Deletion { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. /// are tracked. location: &'a BStr, /// The mode of the deleted entry. entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The object id of the deleted entry. id: gix_hash::ObjectId, }, /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning /// a file into a symbolic link adjusts its mode. Modification { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. /// are tracked. location: &'a BStr, /// The mode of the entry before the modification. previous_entry_mode: gix_object::tree::EntryMode, /// The object id of the entry before the modification. previous_id: gix_hash::ObjectId, /// The mode of the entry after the modification. entry_mode: gix_object::tree::EntryMode, /// The object id after the modification. id: gix_hash::ObjectId, }, /// Entries are considered rewritten if they are not trees and they, according to some understanding of identity, were renamed /// or copied. /// In case of renames, this means they originally appeared as [`Deletion`](ChangeRef::Deletion) signalling their source as well as an /// [`Addition`](ChangeRef::Addition) acting as destination. /// /// In case of copies, the `copy` flag is true and typically represents a perfect copy of a source was made. /// /// This variant can only be encountered if [rewrite tracking](super::Options::rewrites) is enabled. /// /// Note that mode changes may have occurred as well, i.e. changes from executable to non-executable or vice-versa. Rewrite { /// The location of the source of the rename or copy operation. /// /// It may be empty if [file names](super::Options::location) is `None`. /// are tracked. source_location: &'a BStr, /// The mode of the entry before the rename. source_entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between the source and another source, /// making it easy to reconstruct the top-level of directory changes. source_relation: Option<tree::visit::Relation>, /// The object id of the entry before the rename. /// /// Note that this is the same as `id` if we require the [similarity to be 100%](super::Rewrites::percentage), but may /// be different otherwise. source_id: gix_hash::ObjectId, /// Information about the diff we performed to detect similarity and match the `source_id` with the current state at `id`. /// It's `None` if `source_id` is equal to `id`, as identity made an actual diff computation unnecessary. diff: Option<DiffLineStats>, /// The mode of the entry after the rename. /// It could differ but still be considered a rename as we are concerned only about content. entry_mode: gix_object::tree::EntryMode, /// The object id after the rename. id: gix_hash::ObjectId, /// The location after the rename or copy operation. /// /// It may be empty if [file names](super::Options::location) is `None`. location: &'a BStr, /// Identifies a relationship between this destination and another destination, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// If true, this rewrite is created by copy, and `source_id` is pointing to its source. Otherwise, it's a rename, and `source_id` /// points to a deleted object, as renames are tracked as deletions and additions of the same or similar content. copy: bool, },} /// Represents any possible change in order to turn one tree into another, with fully-owned data.#[derive(Debug, Clone, PartialEq)]pub enum Change { /// An entry was added, like the addition of a file or directory. Addition { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The mode of the added entry. entry_mode: gix_object::tree::EntryMode, /// The object id of the added entry. id: gix_hash::ObjectId, }, /// An entry was deleted, like the deletion of a file or directory. Deletion { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The mode of the deleted entry. entry_mode: gix_object::tree::EntryMode, /// The object id of the deleted entry. id: gix_hash::ObjectId, }, /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning /// a file into a symbolic link adjusts its mode. Modification { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// The mode of the entry before the modification. previous_entry_mode: gix_object::tree::EntryMode, /// The object id of the entry before the modification. previous_id: gix_hash::ObjectId, /// The mode of the entry after the modification. entry_mode: gix_object::tree::EntryMode, /// The object id after the modification. id: gix_hash::ObjectId, }, /// Entries are considered rewritten if they are not trees and they, according to some understanding of identity, were renamed /// or copied. /// In case of renames, this means they originally appeared as [`Deletion`](ChangeRef::Deletion) signalling their source as well as an /// [`Addition`](ChangeRef::Addition) acting as destination. /// /// In case of copies, the `copy` flag is true and typically represents a perfect copy of a source was made. /// /// This variant can only be encountered if [rewrite tracking](super::Options::rewrites) is enabled. /// /// Note that mode changes may have occurred as well, i.e. changes from executable to non-executable or vice-versa. Rewrite { /// The location of the source of the rename operation. /// /// It may be empty if [file names](super::Options::location) is `None`. source_location: BString, /// The mode of the entry before the rename. source_entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between the source and another source, /// making it easy to reconstruct the top-level of directory changes. source_relation: Option<tree::visit::Relation>, /// The object id of the entry before the rename. /// /// Note that this is the same as `id` if we require the [similarity to be 100%](super::Rewrites::percentage), but may /// be different otherwise. source_id: gix_hash::ObjectId, /// Information about the diff we performed to detect similarity and match the `source_id` with the current state at `id`. /// It's `None` if `source_id` is equal to `id`, as identity made an actual diff computation unnecessary. diff: Option<DiffLineStats>, /// The mode of the entry after the rename. /// It could differ but still be considered a rename as we are concerned only about content. entry_mode: gix_object::tree::EntryMode, /// The object id after the rename. id: gix_hash::ObjectId, /// The location after the rename or copy operation. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// Identifies a relationship between this destination and another destination, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// If true, this rewrite is created by copy, and `source_id` is pointing to its source. Otherwise, it's a rename, and `source_id` /// points to a deleted object, as renames are tracked as deletions and additions of the same or similar content. copy: bool, },} /// Lifecycleimpl ChangeRef<'_> { /// Copy this instance into a fully-owned version pub fn into_owned(self) -> Change { match self { ChangeRef::Addition { location, entry_mode, id, relation, } => Change::Addition { location: location.to_owned(), entry_mode, id, relation, }, ChangeRef::Deletion { location, entry_mode, id, relation, } => Change::Deletion { location: location.to_owned(), entry_mode, id, relation, }, ChangeRef::Modification { location, previous_entry_mode, previous_id, entry_mode, id, } => Change::Modification { location: location.to_owned(), previous_entry_mode, previous_id, entry_mode, id, }, ChangeRef::Rewrite { source_location, source_relation, source_entry_mode, source_id, diff, entry_mode, id, location, relation, copy, } => Change::Rewrite { source_location: source_location.to_owned(), source_relation, source_entry_mode, source_id, diff, entry_mode, id, location: location.to_owned(), relation, copy, }, } }} /// Lifecycleimpl Change { /// Return an attached version of this instance that uses `old_repo` for previous values and `new_repo` for current values. pub fn to_ref(&self) -> ChangeRef<'_> { match self { Change::Addition { location, relation, entry_mode, id, } => ChangeRef::Addition { location: location.as_bstr(), entry_mode: *entry_mode, id: *id, relation: *relation, }, Change::Deletion { location, relation, entry_mode, id, } => ChangeRef::Deletion { location: location.as_bstr(), entry_mode: *entry_mode, id: *id, relation: *relation, }, Change::Modification { location, previous_entry_mode, previous_id, entry_mode, id, } => ChangeRef::Modification { location: location.as_bstr(), previous_entry_mode: *previous_entry_mode, previous_id: *previous_id, entry_mode: *entry_mode, id: *id, }, Change::Rewrite { source_location, source_relation, source_entry_mode, source_id, diff, entry_mode, id, location, relation, copy, } => ChangeRef::Rewrite { source_location: source_location.as_ref(), source_relation: *source_relation, source_entry_mode: *source_entry_mode, source_id: *source_id, diff: *diff, entry_mode: *entry_mode, id: *id, location: location.as_bstr(), relation: *relation, copy: *copy, }, } }} impl crate::blob::Platform { /// Set ourselves up to produces blob-diffs from `change`, so this platform can be used to produce diffs easily. /// `objects` are used to fetch object data as needed. /// /// ### Warning about Memory Consumption /// /// This instance only grows, so one should call [`crate::blob::Platform::clear_resource_cache`] occasionally. pub fn set_resource_by_change( &mut self, change: ChangeRef<'_>, objects: &impl gix_object::FindObjectOrHeader, ) -> Result<&mut Self, crate::blob::platform::set_resource::Error> { match change { ChangeRef::Addition { location, relation: _, entry_mode, id, } => { self.set_resource( id.kind().null(), entry_mode.kind(), location, ResourceKind::OldOrSource, objects, )?; self.set_resource(id, entry_mode.kind(), location, ResourceKind::NewOrDestination, objects)?; } ChangeRef::Deletion { location, relation: _, entry_mode, id, } => { self.set_resource(id, entry_mode.kind(), location, ResourceKind::OldOrSource, objects)?; self.set_resource( id.kind().null(), entry_mode.kind(), location, ResourceKind::NewOrDestination, objects, )?; } ChangeRef::Modification { location, previous_entry_mode, previous_id, entry_mode, id, } => { self.set_resource( previous_id, previous_entry_mode.kind(), location, ResourceKind::OldOrSource, objects, )?; self.set_resource(id, entry_mode.kind(), location, ResourceKind::NewOrDestination, objects)?; } ChangeRef::Rewrite { source_location, source_relation: _, source_entry_mode, source_id, entry_mode, id, location, relation: _, diff: _, copy: _, } => { self.set_resource( source_id, source_entry_mode.kind(), source_location, ResourceKind::OldOrSource, objects, )?; self.set_resource(id, entry_mode.kind(), location, ResourceKind::NewOrDestination, objects)?; } } Ok(self) }} impl<'a> ChangeRef<'a> { /// Return the relation this instance may have to other changes. pub fn relation(&self) -> Option<tree::visit::Relation> { match self { ChangeRef::Addition { relation, .. } | ChangeRef::Deletion { relation, .. } | ChangeRef::Rewrite { relation, .. } => *relation, ChangeRef::Modification { .. } => None, } } /// Return the current mode of this instance. pub fn entry_mode(&self) -> gix_object::tree::EntryMode { match self { ChangeRef::Addition { entry_mode, .. } | ChangeRef::Deletion { entry_mode, .. } | ChangeRef::Modification { entry_mode, .. } | ChangeRef::Rewrite { entry_mode, .. } => *entry_mode, } } /// Return the current mode of this instance, along with its object id. pub fn entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) { match self { ChangeRef::Addition { entry_mode, id, .. } | ChangeRef::Deletion { entry_mode, id, .. } | ChangeRef::Modification { entry_mode, id, .. } | ChangeRef::Rewrite { entry_mode, id, .. } => (*entry_mode, id), } } /// Return the *previous* mode and id of the resource where possible, i.e. the source of a rename or copy, or a modification. pub fn source_entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) { match self { ChangeRef::Addition { entry_mode, id, .. } | ChangeRef::Deletion { entry_mode, id, .. } | ChangeRef::Modification { previous_entry_mode: entry_mode, previous_id: id, .. } | ChangeRef::Rewrite { source_entry_mode: entry_mode, source_id: id, .. } => (*entry_mode, id), } } /// Return the *current* location of the resource, i.e. the destination of a rename or copy, or the /// location at which an addition, deletion or modification took place. pub fn location(&self) -> &'a BStr { match self { ChangeRef::Addition { location, .. } | ChangeRef::Deletion { location, .. } | ChangeRef::Modification { location, .. } | ChangeRef::Rewrite { location, .. } => location, } } /// Return the *previous* location of the resource where possible, i.e. the source of a rename or copy, or the /// location at which an addition, deletion or modification took place. pub fn source_location(&self) -> &BStr { match self { ChangeRef::Addition { location, .. } | ChangeRef::Deletion { location, .. } | ChangeRef::Modification { location, .. } => location, ChangeRef::Rewrite { source_location, .. } => source_location, } }} impl Change { /// Return the relation this instance may have to other changes. pub fn relation(&self) -> Option<tree::visit::Relation> { match self { Change::Addition { relation, .. } | Change::Deletion { relation, .. } | Change::Rewrite { relation, .. } => *relation, Change::Modification { .. } => None, } } Lines 1–500 of 560. Load more
use bstr::{BStr, BString, ByteSlice}; use crate::{ blob::{DiffLineStats, ResourceKind}, tree, }; /// Represents any possible change in order to turn one tree into another, which references data owned by its producer. #[derive(Debug, Clone, Copy, PartialEq)] pub enum ChangeRef<'a> { /// An entry was added, like the addition of a file or directory. Addition { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: &'a BStr, /// The mode of the added entry. entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The object id of the added entry. id: gix_hash::ObjectId, }, /// An entry was deleted, like the deletion of a file or directory. Deletion { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. /// are tracked. location: &'a BStr, /// The mode of the deleted entry. entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The object id of the deleted entry. id: gix_hash::ObjectId, }, /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning /// a file into a symbolic link adjusts its mode. Modification { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. /// are tracked. location: &'a BStr, /// The mode of the entry before the modification. previous_entry_mode: gix_object::tree::EntryMode, /// The object id of the entry before the modification. previous_id: gix_hash::ObjectId, /// The mode of the entry after the modification. entry_mode: gix_object::tree::EntryMode, /// The object id after the modification. id: gix_hash::ObjectId, }, /// Entries are considered rewritten if they are not trees and they, according to some understanding of identity, were renamed /// or copied. /// In case of renames, this means they originally appeared as [`Deletion`](ChangeRef::Deletion) signalling their source as well as an /// [`Addition`](ChangeRef::Addition) acting as destination. /// /// In case of copies, the `copy` flag is true and typically represents a perfect copy of a source was made. /// /// This variant can only be encountered if [rewrite tracking](super::Options::rewrites) is enabled. /// /// Note that mode changes may have occurred as well, i.e. changes from executable to non-executable or vice-versa. Rewrite { /// The location of the source of the rename or copy operation. /// /// It may be empty if [file names](super::Options::location) is `None`. /// are tracked. source_location: &'a BStr, /// The mode of the entry before the rename. source_entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between the source and another source, /// making it easy to reconstruct the top-level of directory changes. source_relation: Option<tree::visit::Relation>, /// The object id of the entry before the rename. /// /// Note that this is the same as `id` if we require the [similarity to be 100%](super::Rewrites::percentage), but may /// be different otherwise. source_id: gix_hash::ObjectId, /// Information about the diff we performed to detect similarity and match the `source_id` with the current state at `id`. /// It's `None` if `source_id` is equal to `id`, as identity made an actual diff computation unnecessary. diff: Option<DiffLineStats>, /// The mode of the entry after the rename. /// It could differ but still be considered a rename as we are concerned only about content. entry_mode: gix_object::tree::EntryMode, /// The object id after the rename. id: gix_hash::ObjectId, /// The location after the rename or copy operation. /// /// It may be empty if [file names](super::Options::location) is `None`. location: &'a BStr, /// Identifies a relationship between this destination and another destination, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// If true, this rewrite is created by copy, and `source_id` is pointing to its source. Otherwise, it's a rename, and `source_id` /// points to a deleted object, as renames are tracked as deletions and additions of the same or similar content. copy: bool, }, } /// Represents any possible change in order to turn one tree into another, with fully-owned data. #[derive(Debug, Clone, PartialEq)] pub enum Change { /// An entry was added, like the addition of a file or directory. Addition { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The mode of the added entry. entry_mode: gix_object::tree::EntryMode, /// The object id of the added entry. id: gix_hash::ObjectId, }, /// An entry was deleted, like the deletion of a file or directory. Deletion { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// Identifies a relationship between this instance and another one, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// The mode of the deleted entry. entry_mode: gix_object::tree::EntryMode, /// The object id of the deleted entry. id: gix_hash::ObjectId, }, /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning /// a file into a symbolic link adjusts its mode. Modification { /// The location of the file or directory. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// The mode of the entry before the modification. previous_entry_mode: gix_object::tree::EntryMode, /// The object id of the entry before the modification. previous_id: gix_hash::ObjectId, /// The mode of the entry after the modification. entry_mode: gix_object::tree::EntryMode, /// The object id after the modification. id: gix_hash::ObjectId, }, /// Entries are considered rewritten if they are not trees and they, according to some understanding of identity, were renamed /// or copied. /// In case of renames, this means they originally appeared as [`Deletion`](ChangeRef::Deletion) signalling their source as well as an /// [`Addition`](ChangeRef::Addition) acting as destination. /// /// In case of copies, the `copy` flag is true and typically represents a perfect copy of a source was made. /// /// This variant can only be encountered if [rewrite tracking](super::Options::rewrites) is enabled. /// /// Note that mode changes may have occurred as well, i.e. changes from executable to non-executable or vice-versa. Rewrite { /// The location of the source of the rename operation. /// /// It may be empty if [file names](super::Options::location) is `None`. source_location: BString, /// The mode of the entry before the rename. source_entry_mode: gix_object::tree::EntryMode, /// Identifies a relationship between the source and another source, /// making it easy to reconstruct the top-level of directory changes. source_relation: Option<tree::visit::Relation>, /// The object id of the entry before the rename. /// /// Note that this is the same as `id` if we require the [similarity to be 100%](super::Rewrites::percentage), but may /// be different otherwise. source_id: gix_hash::ObjectId, /// Information about the diff we performed to detect similarity and match the `source_id` with the current state at `id`. /// It's `None` if `source_id` is equal to `id`, as identity made an actual diff computation unnecessary. diff: Option<DiffLineStats>, /// The mode of the entry after the rename. /// It could differ but still be considered a rename as we are concerned only about content. entry_mode: gix_object::tree::EntryMode, /// The object id after the rename. id: gix_hash::ObjectId, /// The location after the rename or copy operation. /// /// It may be empty if [file names](super::Options::location) is `None`. location: BString, /// Identifies a relationship between this destination and another destination, /// making it easy to reconstruct the top-level of directory changes. relation: Option<tree::visit::Relation>, /// If true, this rewrite is created by copy, and `source_id` is pointing to its source. Otherwise, it's a rename, and `source_id` /// points to a deleted object, as renames are tracked as deletions and additions of the same or similar content. copy: bool, }, } /// Lifecycle impl ChangeRef<'_> { /// Copy this instance into a fully-owned version pub fn into_owned(self) -> Change { match self { ChangeRef::Addition { location, entry_mode, id, relation, } => Change::Addition { location: location.to_owned(), entry_mode, id, relation, }, ChangeRef::Deletion { location, entry_mode, id, relation, } => Change::Deletion { location: location.to_owned(), entry_mode, id, relation, }, ChangeRef::Modification { location, previous_entry_mode, previous_id, entry_mode, id, } => Change::Modification { location: location.to_owned(), previous_entry_mode, previous_id, entry_mode, id, }, ChangeRef::Rewrite { source_location, source_relation, source_entry_mode, source_id, diff, entry_mode, id, location, relation, copy, } => Change::Rewrite { source_location: source_location.to_owned(), source_relation, source_entry_mode, source_id, diff, entry_mode, id, location: location.to_owned(), relation, copy, }, } } } /// Lifecycle impl Change { /// Return an attached version of this instance that uses `old_repo` for previous values and `new_repo` for current values. pub fn to_ref(&self) -> ChangeRef<'_> { match self { Change::Addition { location, relation, entry_mode, id, } => ChangeRef::Addition { location: location.as_bstr(), entry_mode: *entry_mode, id: *id, relation: *relation, }, Change::Deletion { location, relation, entry_mode, id, } => ChangeRef::Deletion { location: location.as_bstr(), entry_mode: *entry_mode, id: *id, relation: *relation, }, Change::Modification { location, previous_entry_mode, previous_id, entry_mode, id, } => ChangeRef::Modification { location: location.as_bstr(), previous_entry_mode: *previous_entry_mode, previous_id: *previous_id, entry_mode: *entry_mode, id: *id, }, Change::Rewrite { source_location, source_relation, source_entry_mode, source_id, diff, entry_mode, id, location, relation, copy, } => ChangeRef::Rewrite { source_location: source_location.as_ref(), source_relation: *source_relation, source_entry_mode: *source_entry_mode, source_id: *source_id, diff: *diff, entry_mode: *entry_mode, id: *id, location: location.as_bstr(), relation: *relation, copy: *copy, }, } } } impl crate::blob::Platform { /// Set ourselves up to produces blob-diffs from `change`, so this platform can be used to produce diffs easily. /// `objects` are used to fetch object data as needed. /// /// ### Warning about Memory Consumption /// /// This instance only grows, so one should call [`crate::blob::Platform::clear_resource_cache`] occasionally. pub fn set_resource_by_change( &mut self, change: ChangeRef<'_>, objects: &impl gix_object::FindObjectOrHeader, ) -> Result<&mut Self, crate::blob::platform::set_resource::Error> { match change { ChangeRef::Addition { location, relation: _, entry_mode, id, } => { self.set_resource( id.kind().null(), entry_mode.kind(), location, ResourceKind::OldOrSource, objects, )?; self.set_resource(id, entry_mode.kind(), location, ResourceKind::NewOrDestination, objects)?; } ChangeRef::Deletion { location, relation: _, entry_mode, id, } => { self.set_resource(id, entry_mode.kind(), location, ResourceKind::OldOrSource, objects)?; self.set_resource( id.kind().null(), entry_mode.kind(), location, ResourceKind::NewOrDestination, objects, )?; } ChangeRef::Modification { location, previous_entry_mode, previous_id, entry_mode, id, } => { self.set_resource( previous_id, previous_entry_mode.kind(), location, ResourceKind::OldOrSource, objects, )?; self.set_resource(id, entry_mode.kind(), location, ResourceKind::NewOrDestination, objects)?; } ChangeRef::Rewrite { source_location, source_relation: _, source_entry_mode, source_id, entry_mode, id, location, relation: _, diff: _, copy: _, } => { self.set_resource( source_id, source_entry_mode.kind(), source_location, ResourceKind::OldOrSource, objects, )?; self.set_resource(id, entry_mode.kind(), location, ResourceKind::NewOrDestination, objects)?; } } Ok(self) } } impl<'a> ChangeRef<'a> { /// Return the relation this instance may have to other changes. pub fn relation(&self) -> Option<tree::visit::Relation> { match self { ChangeRef::Addition { relation, .. } | ChangeRef::Deletion { relation, .. } | ChangeRef::Rewrite { relation, .. } => *relation, ChangeRef::Modification { .. } => None, } } /// Return the current mode of this instance. pub fn entry_mode(&self) -> gix_object::tree::EntryMode { match self { ChangeRef::Addition { entry_mode, .. } | ChangeRef::Deletion { entry_mode, .. } | ChangeRef::Modification { entry_mode, .. } | ChangeRef::Rewrite { entry_mode, .. } => *entry_mode, } } /// Return the current mode of this instance, along with its object id. pub fn entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) { match self { ChangeRef::Addition { entry_mode, id, .. } | ChangeRef::Deletion { entry_mode, id, .. } | ChangeRef::Modification { entry_mode, id, .. } | ChangeRef::Rewrite { entry_mode, id, .. } => (*entry_mode, id), } } /// Return the *previous* mode and id of the resource where possible, i.e. the source of a rename or copy, or a modification. pub fn source_entry_mode_and_id(&self) -> (gix_object::tree::EntryMode, &gix_hash::oid) { match self { ChangeRef::Addition { entry_mode, id, .. } | ChangeRef::Deletion { entry_mode, id, .. } | ChangeRef::Modification { previous_entry_mode: entry_mode, previous_id: id, .. } | ChangeRef::Rewrite { source_entry_mode: entry_mode, source_id: id, .. } => (*entry_mode, id), } } /// Return the *current* location of the resource, i.e. the destination of a rename or copy, or the /// location at which an addition, deletion or modification took place. pub fn location(&self) -> &'a BStr { match self { ChangeRef::Addition { location, .. } | ChangeRef::Deletion { location, .. } | ChangeRef::Modification { location, .. } | ChangeRef::Rewrite { location, .. } => location, } } /// Return the *previous* location of the resource where possible, i.e. the source of a rename or copy, or the /// location at which an addition, deletion or modification took place. pub fn source_location(&self) -> &BStr { match self { ChangeRef::Addition { location, .. } | ChangeRef::Deletion { location, .. } | ChangeRef::Modification { location, .. } => location, ChangeRef::Rewrite { source_location, .. } => source_location, } } } impl Change { /// Return the relation this instance may have to other changes. pub fn relation(&self) -> Option<tree::visit::Relation> { match self { Change::Addition { relation, .. } | Change::Deletion { relation, .. } | Change::Rewrite { relation, .. } => *relation, Change::Modification { .. } => None, } }