Skip to main content

opys_core/
extract.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
4pub struct ExtractPick {
5    pub file: String,
6    pub into: String,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct ExtractScan {
11    pub matches: String,
12    pub into: String,
13    /// Path-prefixes to strip off each matched entry, tried in order. A
14    /// literal string is a plain prefix; `*<suffix>` strips up through the
15    /// first occurrence of `<suffix>` regardless of what precedes it — e.g.
16    /// `"*/"` drops an archive's top-level directory whatever it's named
17    /// (for archives whose internal directory embeds a build identifier
18    /// unknowable ahead of time).
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub strip: Option<Vec<String>>,
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub includes: Option<Vec<String>>,
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub excludes: Option<Vec<String>>,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
28pub struct ExtractDump {
29    pub into: String,
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub clean: Option<bool>,
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub includes: Option<Vec<String>>,
34    #[serde(default, skip_serializing_if = "Option::is_none")]
35    pub excludes: Option<Vec<String>>,
36}
37
38/// A single extract rule, discriminated structurally on the wire (which
39/// field is present: `file` → Pick, `matches` → Scan, otherwise Dump).
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(untagged)]
42pub enum ExtractRule {
43    Pick(ExtractPick),
44    Scan(ExtractScan),
45    Dump(ExtractDump),
46}
47
48/// Wire form: one rule or many. Decoding flattens both into `Vec<ExtractRule>`;
49/// encoding emits the bare object when the list has exactly one entry.
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
51#[serde(untagged)]
52pub enum ExtractWire {
53    One(ExtractRule),
54    Many(Vec<ExtractRule>),
55}
56
57pub fn decode_extract(raw: ExtractWire) -> Vec<ExtractRule> {
58    match raw {
59        ExtractWire::One(r) => vec![r],
60        ExtractWire::Many(v) => v,
61    }
62}
63
64pub fn encode_extract(rules: &[ExtractRule]) -> ExtractWire {
65    if rules.len() == 1 {
66        ExtractWire::One(rules[0].clone())
67    } else {
68        ExtractWire::Many(rules.to_vec())
69    }
70}