55
66use facet_git_tree:: { Edge , Migration , ObjectId , Schema , apply_chain} ;
77use facet_value:: Value ;
8- use gix:: objs:: { Find , Write } ;
8+ use gix:: objs:: { Data , Find , Kind , Tree , TreeRef , Write , WriteTo } ;
99use gix_refstore:: RefStore ;
1010
1111use crate :: error:: Error ;
8080
8181/// One step of a chain: the document values on this side conform to, and the
8282/// migration off it.
83+ pub ( crate ) fn read_schema_document < F : Find + ?Sized > (
84+ tree : & ObjectId ,
85+ store : & F ,
86+ ) -> Result < Schema , Error > {
87+ let filtered = WithoutMigration { tree, store } ;
88+ Ok ( Schema :: read_pinned ( tree, & filtered) ?)
89+ }
90+
91+ struct WithoutMigration < ' a , F : ?Sized > {
92+ tree : & ' a ObjectId ,
93+ store : & ' a F ,
94+ }
95+
96+ impl < F : Find + ?Sized > Find for WithoutMigration < ' _ , F > {
97+ fn try_find < ' a > (
98+ & self ,
99+ id : & gix:: hash:: oid ,
100+ buffer : & ' a mut Vec < u8 > ,
101+ ) -> Result < Option < Data < ' a > > , gix:: objs:: find:: Error > {
102+ let Some ( ( kind, object_hash, bytes) ) = ( || {
103+ let mut source = Vec :: new ( ) ;
104+ self . store . try_find ( id, & mut source) . map ( |object| {
105+ object. map ( |object| ( object. kind , object. object_hash , object. data . to_vec ( ) ) )
106+ } )
107+ } ) ( ) ?
108+ else {
109+ return Ok ( None ) ;
110+ } ;
111+ let bytes = if id == self . tree . as_ref ( ) && kind == Kind :: Tree {
112+ let entries = TreeRef :: from_bytes ( & bytes, object_hash)
113+ . map_err ( |error| Box :: new ( error) as gix:: objs:: find:: Error ) ?
114+ . entries
115+ . into_iter ( )
116+ . filter ( |entry| entry. filename != ENTRY )
117+ . map ( |entry| gix:: objs:: tree:: Entry {
118+ mode : entry. mode ,
119+ filename : entry. filename . to_owned ( ) ,
120+ oid : ObjectId :: from ( entry. oid . to_owned ( ) ) ,
121+ } )
122+ . collect ( ) ;
123+ let mut filtered = Vec :: new ( ) ;
124+ Tree { entries }
125+ . write_to ( & mut filtered)
126+ . map_err ( |error| Box :: new ( error) as gix:: objs:: find:: Error ) ?;
127+ filtered
128+ } else {
129+ bytes
130+ } ;
131+ * buffer = bytes;
132+ Ok ( Some ( Data {
133+ kind,
134+ object_hash,
135+ data : buffer,
136+ } ) )
137+ }
138+ }
139+
83140struct Step {
84141 from : Schema ,
85142 migration : Migration ,
@@ -111,7 +168,7 @@ where
111168 kind : self . kind . clone ( ) ,
112169 } ) ?;
113170 let tree = self . store . commit_tree ( tip) ?;
114- let schema = Schema :: read_pinned ( & tree, self . store . objects ( ) ) ?;
171+ let schema = read_schema_document ( & tree, self . store . objects ( ) ) ?;
115172 Ok ( TargetSchema :: new ( schema, history) )
116173 }
117174
@@ -152,8 +209,8 @@ where
152209 kind : self . kind . clone ( ) ,
153210 } ) ?;
154211 let target_tree = self . store . commit_tree ( tip) ?;
155- let stored_target = self . store . schema ( target_tree ) ?;
156- if stored_target. as_ref ( ) != target. schema ( ) || target. schema ( ) . kind != self . kind . as_str ( ) {
212+ let stored_target = read_schema_document ( & target_tree , self . store . objects ( ) ) ?;
213+ if stored_target != * target. schema ( ) || target. schema ( ) . kind != self . kind . as_str ( ) {
157214 return Err ( Error :: TargetSchemaMismatch {
158215 kind : self . kind . clone ( ) ,
159216 commit : tip,
@@ -172,7 +229,7 @@ where
172229 let ( newer, older) = ( pair[ 0 ] , pair[ 1 ] ) ;
173230 let older_tree = self . store . commit_tree ( older) ?;
174231 steps. push ( Step {
175- from : Schema :: read_pinned ( & older_tree, self . store . objects ( ) ) ?,
232+ from : read_schema_document ( & older_tree, self . store . objects ( ) ) ?,
176233 migration : self . migration_at ( newer) ?. ok_or ( Error :: MigrationMissing {
177234 kind : self . kind . clone ( ) ,
178235 commit : newer,
0 commit comments