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