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
111111
112112 pub(crate) mod access {
113113 pub(crate) mod object {
114− use crate::hash::oid;
115− use crate::odb::{Find, FindExt};
116− use crate::{object, Access, ObjectRef, Oid};
114+ use std::{cell::Ref, ops::DerefMut};
115+
117116 use git_hash::ObjectId;
118− use std::cell::Ref;
119− use std::ops::DerefMut;
117+
118+ use crate::{
119+ hash::oid,
120+ object,
121+ odb::{Find, FindExt},
122+ Access, ObjectRef, Oid,
123+ };
120124
121125 pub fn find_existing_object<A: Access + Sized>(
122126 access: &A,
git-repository/src/lib.rs+9−0
@@ -24,6 +24,8 @@ · 23 unmodified lines
2424 //! * Objects with `Ref` suffix can only exist one at a time unless they are transformed into an owned version of it
2525 //! * `ObjectRef` blocks the current buffer, hence many operations that use the buffer are consuming
2626 //! * 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.
2729 //! * git-repository functions return `Oid` for oids if they originate in something having or being `Access`
2830 //!
2931 //! #### Limitations
@@ -151,6 +153,13 @@ pub struct ObjectRef<'repo, A> { · 121 unmodified lines
151153 access: &'repo A,
152154 }
153155
156+#[derive(Clone)]
157+pub struct Object {
158+ pub id: ObjectId,
159+ pub kind: objs::Kind,
160+ pub data: Vec<u8>,
161+}
162+
154163 pub mod object;
155164
156165 pub struct Reference<'r, A> {
git-repository/src/object.rs+93−12
@@ -1,20 +1,22 @@
1−use std::{cell::Ref, ops::DerefMut};
1+use std::{borrow::Borrow, cell::Ref, ops::DerefMut};
22
33 pub use git_object::Kind;
44
5−use crate::objs::immutable;
6−use crate::odb::Find;
75 use crate::{
86 hash::{oid, ObjectId},
9− object, odb,
10− odb::FindExt,
11− Access, ObjectRef, Oid,
7+ object,
8+ objs::immutable,
9+ odb,
10+ odb::{Find, FindExt},
11+ Access, Object, ObjectRef, Oid,
1212 };
13−use std::borrow::Borrow;
1413
15−mod impls {
14+mod oid_impls {
1615 use super::Oid;
17− use crate::hash::{oid, ObjectId};
16+ use crate::{
17+ hash::{oid, ObjectId},
18+ Object, ObjectRef,
19+ };
1820
1921 impl<'repo, A, B> PartialEq<Oid<'repo, A>> for Oid<'repo, B> {
2022 fn eq(&self, other: &Oid<'repo, A>) -> bool {
@@ -28,6 +30,24 @@ mod impls { · 7 unmodified lines
2830 }
2931 }
3032
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+
3151 impl<'repo, A> std::fmt::Debug for Oid<'repo, A> {
3252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3353 self.id.fmt(f)
@@ -47,6 +67,21 @@ mod impls { · 13 unmodified lines
4767 }
4868 }
4969
70+impl 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+
5085 impl<'repo, A> ObjectRef<'repo, A>
5186 where
5287 A: Access + Sized,
@@ -72,6 +107,50 @@ pub mod find { · 19 unmodified lines
72107 }
73108 }
74109
110+mod 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+
132+impl<'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+
75154 impl<'repo, A> ObjectRef<'repo, A>
76155 where
77156 A: Access + Sized,
@@ -86,6 +165,11 @@ where · 8 unmodified lines
86165 }
87166
88167 pub mod peel_to_kind {
168+ use crate::{
169+ object::{peel_to_kind, Kind},
170+ objs::immutable,
171+ odb, Access, ObjectRef,
172+ };
89173
90174 impl<'repo, A> ObjectRef<'repo, A>
91175 where
@@ -140,9 +224,6 @@ pub mod peel_to_kind { · 48 unmodified lines
140224 }
141225 }
142226 }
143− use crate::object::{peel_to_kind, Kind};
144− use crate::objs::immutable;
145− use crate::{odb, Access, ObjectRef};
146227 pub use error::Error;
147228 }
148229
git-repository/src/reference.rs+1−0
@@ -37,6 +37,7 @@ pub mod peel_to_id_in_place { · 36 unmodified lines
3737 }
3838 }
3939
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.
4041 impl<'repo, A> Reference<'repo, A>
4142 where
4243 A: Access + Sized,
git-repository/tests/object/mod.rs+1−2
@@ -1,5 +1,4 @@
1−use git_repository::ObjectRef;
2−use git_repository::Oid;
1+use git_repository::{ObjectRef, Oid};
32
43 #[test]
54 fn object_ref_size_in_memory() {