gix_merge/blob/platform/
set_resource.rs1use bstr::{BStr, BString};
2
3use crate::blob::{pipeline, platform::Resource, Platform, ResourceKind};
4
5#[derive(Debug, thiserror::Error)]
7#[allow(missing_docs)]
8pub enum Error {
9 #[error("Can only diff blobs, not {mode:?}")]
10 InvalidMode { mode: gix_object::tree::EntryKind },
11 #[error("Failed to read {kind:?} worktree data from '{rela_path}'")]
12 Io {
13 rela_path: BString,
14 kind: ResourceKind,
15 source: std::io::Error,
16 },
17 #[error("Failed to obtain attributes for {kind:?} resource at '{rela_path}'")]
18 Attributes {
19 rela_path: BString,
20 kind: ResourceKind,
21 source: std::io::Error,
22 },
23 #[error(transparent)]
24 ConvertToMergeable(#[from] pipeline::convert_to_mergeable::Error),
25}
26
27impl Platform {
29 pub fn set_resource(
41 &mut self,
42 id: gix_hash::ObjectId,
43 mode: gix_object::tree::EntryKind,
44 rela_path: &BStr,
45 kind: ResourceKind,
46 objects: &impl gix_object::FindObjectOrHeader,
47 ) -> Result<(), Error> {
48 if !matches!(
49 mode,
50 gix_object::tree::EntryKind::Blob | gix_object::tree::EntryKind::BlobExecutable
51 ) {
52 return Err(Error::InvalidMode { mode });
53 }
54 let entry = self
55 .attr_stack
56 .at_entry(rela_path, None, objects)
57 .map_err(|err| Error::Attributes {
58 source: err,
59 kind,
60 rela_path: rela_path.to_owned(),
61 })?;
62
63 let storage = match kind {
64 ResourceKind::OtherOrTheirs => &mut self.other,
65 ResourceKind::CommonAncestorOrBase => &mut self.ancestor,
66 ResourceKind::CurrentOrOurs => &mut self.current,
67 };
68
69 let mut buf_storage = Vec::new();
70 let out = self.filter.convert_to_mergeable(
71 &id,
72 mode,
73 rela_path,
74 kind,
75 &mut |_, out| {
76 let _ = entry.matching_attributes(out);
77 },
78 objects,
79 self.filter_mode,
80 storage.as_mut().map_or(&mut buf_storage, |s| &mut s.buffer),
81 )?;
82
83 match storage {
84 None => {
85 *storage = Some(Resource {
86 id,
87 rela_path: rela_path.to_owned(),
88 data: out,
89 mode,
90 buffer: buf_storage,
91 });
92 }
93 Some(storage) => {
94 storage.id = id;
95 storage.rela_path = rela_path.to_owned();
96 storage.data = out;
97 storage.mode = mode;
98 }
99 }
100 Ok(())
101 }
102}