History

[repository #162] detachable ObjectRefs and a few conversions

Sebastian Thiel committed 5 years ago

Commit ec123bb1 parent ba243a35 files · +113 −19Browse files

Unified · Split

5 files
  1. git-repository/src/ext.rs +9 −5
  2. git-repository/src/lib.rs +9 −0
  3. git-repository/src/object.rs +93 −12
  4. git-repository/src/reference.rs +1 −0
  5. git-repository/tests/object/mod.rs +1 −2
git-repository/src/ext.rs+9−5
@@ -111,12 +111,16 @@ pub use object_id::ObjectIdExt; · 110 unmodified lines
111 111
112pub(crate) mod access {112pub(crate) mod access {
113 pub(crate) mod object {113 pub(crate) mod object {
114 use crate::hash::oid;114 use std::{cell::Ref, ops::DerefMut};
115 use crate::odb::{Find, FindExt};115
116 use crate::{object, Access, ObjectRef, Oid};
117 use git_hash::ObjectId;116 use git_hash::ObjectId;
118 use std::cell::Ref;117
119 use std::ops::DerefMut;118 use crate::{
119 hash::oid,
120 object,
121 odb::{Find, FindExt},
122 Access, ObjectRef, Oid,
123 };
120 124
121 pub fn find_existing_object<A: Access + Sized>(125 pub fn find_existing_object<A: Access + Sized>(
122 access: &A,126 access: &A,
git-repository/src/lib.rs+9−0
@@ -24,6 +24,8 @@ · 23 unmodified lines
24//! * Objects with `Ref` suffix can only exist one at a time unless they are transformed into an owned version of it24//! * Objects with `Ref` suffix can only exist one at a time unless they are transformed into an owned version of it
25//! * `ObjectRef` blocks the current buffer, hence many operations that use the buffer are consuming25//! * `ObjectRef` blocks the current buffer, hence many operations that use the buffer are consuming
26//! * There can only be one `Object` at a time, but as many `Oids` as you want.26//! * There can only be one `Object` at a time, but as many `Oids` as you want.
27//! * Anything attached to `Access` can be detached to lift the object limit or make them `Send` able. They can be `attached` to another
28//! `Access` if needed.
27//! * git-repository functions return `Oid` for oids if they originate in something having or being `Access`29//! * git-repository functions return `Oid` for oids if they originate in something having or being `Access`
28//!30//!
29//! #### Limitations31//! #### Limitations
@@ -151,6 +153,13 @@ pub struct ObjectRef<'repo, A> { · 121 unmodified lines
151 access: &'repo A,153 access: &'repo A,
152}154}
153 155
156#[derive(Clone)]
157pub struct Object {
158 pub id: ObjectId,
159 pub kind: objs::Kind,
160 pub data: Vec<u8>,
161}
162
154pub mod object;163pub mod object;
155 164
156pub struct Reference<'r, A> {165pub struct Reference<'r, A> {
git-repository/src/object.rs+93−12
@@ -1,20 +1,22 @@
1use std::{cell::Ref, ops::DerefMut};1use std::{borrow::Borrow, cell::Ref, ops::DerefMut};
2 2
3pub use git_object::Kind;3pub use git_object::Kind;
4 4
5use crate::objs::immutable;
6use crate::odb::Find;
7use crate::{5use crate::{
8 hash::{oid, ObjectId},6 hash::{oid, ObjectId},
9 object, odb,7 object,
10 odb::FindExt,8 objs::immutable,
11 Access, ObjectRef, Oid,9 odb,
10 odb::{Find, FindExt},
11 Access, Object, ObjectRef, Oid,
12};12};
13use std::borrow::Borrow;
14 13
15mod impls {14mod oid_impls {
16 use super::Oid;15 use super::Oid;
17 use crate::hash::{oid, ObjectId};16 use crate::{
17 hash::{oid, ObjectId},
18 Object, ObjectRef,
19 };
18 20
19 impl<'repo, A, B> PartialEq<Oid<'repo, A>> for Oid<'repo, B> {21 impl<'repo, A, B> PartialEq<Oid<'repo, A>> for Oid<'repo, B> {
20 fn eq(&self, other: &Oid<'repo, A>) -> bool {22 fn eq(&self, other: &Oid<'repo, A>) -> bool {
@@ -28,6 +30,24 @@ mod impls { · 7 unmodified lines
28 }30 }
29 }31 }
30 32
33 impl<'repo, A> PartialEq<oid> for Oid<'repo, A> {
34 fn eq(&self, other: &oid) -> bool {
35 self.id == other
36 }
37 }
38
39 impl<'repo, A, B> PartialEq<ObjectRef<'repo, A>> for Oid<'repo, B> {
40 fn eq(&self, other: &ObjectRef<'repo, A>) -> bool {
41 self.id == other.id
42 }
43 }
44
45 impl<'repo, A> PartialEq<Object> for Oid<'repo, A> {
46 fn eq(&self, other: &Object) -> bool {
47 self.id == other.id
48 }
49 }
50
31 impl<'repo, A> std::fmt::Debug for Oid<'repo, A> {51 impl<'repo, A> std::fmt::Debug for Oid<'repo, A> {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 self.id.fmt(f)53 self.id.fmt(f)
@@ -47,6 +67,21 @@ mod impls { · 13 unmodified lines
47 }67 }
48}68}
49 69
70impl Object {
71 pub fn attach<A>(self, access: &A) -> ObjectRef<'_, A>
72 where
73 A: Access + Sized,
74 {
75 *access.cache().buf.borrow_mut() = self.data;
76 ObjectRef {
77 id: self.id,
78 kind: self.kind,
79 data: Ref::map(access.cache().buf.borrow(), |v| v.as_slice()),
80 access,
81 }
82 }
83}
84
50impl<'repo, A> ObjectRef<'repo, A>85impl<'repo, A> ObjectRef<'repo, A>
51where86where
52 A: Access + Sized,87 A: Access + Sized,
@@ -72,6 +107,50 @@ pub mod find { · 19 unmodified lines
72 }107 }
73}108}
74 109
110mod object_ref_impls {
111 use crate::{Object, ObjectRef};
112
113 impl<'repo, A> From<ObjectRef<'repo, A>> for Object {
114 fn from(r: ObjectRef<'repo, A>) -> Self {
115 r.into_owned()
116 }
117 }
118
119 impl<'repo, A> AsRef<[u8]> for ObjectRef<'repo, A> {
120 fn as_ref(&self) -> &[u8] {
121 &self.data
122 }
123 }
124
125 impl AsRef<[u8]> for Object {
126 fn as_ref(&self) -> &[u8] {
127 &self.data
128 }
129 }
130}
131
132impl<'repo, A> ObjectRef<'repo, A> {
133 pub fn to_owned(&self) -> Object {
134 Object {
135 id: self.id,
136 kind: self.kind,
137 data: self.data.to_owned(),
138 }
139 }
140
141 pub fn into_owned(self) -> Object {
142 Object {
143 id: self.id,
144 kind: self.kind,
145 data: self.data.to_owned(),
146 }
147 }
148
149 pub fn detach(self) -> Object {
150 self.into()
151 }
152}
153
75impl<'repo, A> ObjectRef<'repo, A>154impl<'repo, A> ObjectRef<'repo, A>
76where155where
77 A: Access + Sized,156 A: Access + Sized,
@@ -86,6 +165,11 @@ where · 8 unmodified lines
86}165}
87 166
88pub mod peel_to_kind {167pub mod peel_to_kind {
168 use crate::{
169 object::{peel_to_kind, Kind},
170 objs::immutable,
171 odb, Access, ObjectRef,
172 };
89 173
90 impl<'repo, A> ObjectRef<'repo, A>174 impl<'repo, A> ObjectRef<'repo, A>
91 where175 where
@@ -140,9 +224,6 @@ pub mod peel_to_kind { · 48 unmodified lines
140 }224 }
141 }225 }
142 }226 }
143 use crate::object::{peel_to_kind, Kind};
144 use crate::objs::immutable;
145 use crate::{odb, Access, ObjectRef};
146 pub use error::Error;227 pub use error::Error;
147}228}
148 229
git-repository/src/reference.rs+1−0
@@ -37,6 +37,7 @@ pub mod peel_to_id_in_place { · 36 unmodified lines
37 }37 }
38}38}
39 39
40// TODO: think about how to detach a Reference. It should essentially be a 'Raw' reference that should exist in `git-ref` rather than here.
40impl<'repo, A> Reference<'repo, A>41impl<'repo, A> Reference<'repo, A>
41where42where
42 A: Access + Sized,43 A: Access + Sized,
git-repository/tests/object/mod.rs+1−2
@@ -1,5 +1,4 @@
1use git_repository::ObjectRef;1use git_repository::{ObjectRef, Oid};
2use git_repository::Oid;
3 2
4#[test]3#[test]
5fn object_ref_size_in_memory() {4fn object_ref_size_in_memory() {