c2pa_status_tracker/status_tracker/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2022 Adobe. All rights reserved.
// This file is licensed to you under the Apache License,
// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
// or the MIT license (http://opensource.org/licenses/MIT),
// at your option.

// Unless required by applicable law or agreed to in writing,
// this software is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
// implied. See the LICENSE-MIT and LICENSE-APACHE files for the
// specific language governing permissions and limitations under
// each license.

use std::{fmt::Debug, iter::Iterator};

use crate::LogItem;

/// A `StatusTracker` is used in the validation logic of c2pa-rs and
/// related crates to control error-handling behavior and optionally
/// aggregate log messages as they are generated.
pub trait StatusTracker: Debug + Send {
    /// Return the current list of validation log items.
    fn logged_items(&self) -> &[LogItem];

    /// Appends the contents of another [`StatusTracker`] to this list of
    /// validation log items.
    fn append(&mut self, other: &impl StatusTracker) {
        for log_item in other.logged_items() {
            self.add_non_error(log_item.clone());
        }
    }

    /// Add a non-error [`LogItem`] to this status tracker.
    ///
    /// Primarily intended for use by [`LogItem::success()`]
    /// or [`LogItem::informational()`].
    fn add_non_error(&mut self, log_item: LogItem);

    /// Add an error-case [`LogItem`] to this status tracker.
    ///
    /// Some implementations are configured to stop immediately on errors. If
    /// so, this function will return `Err(err)`.
    ///
    /// If the implementation is configured to aggregate all log
    /// messages, this function returns `Ok(())`.
    ///
    /// Primarily intended for use by [`LogItem::failure()`].
    fn add_error<E>(&mut self, log_item: LogItem, err: E) -> Result<(), E>;

    /// Return the [`LogItem`]s that have error conditions (`err_val` is
    /// populated).
    ///
    /// Removes matching items from the list of log items.
    fn filter_errors(&mut self) -> impl Iterator<Item = &LogItem> {
        self.logged_items()
            .iter()
            .filter(|item| item.err_val.is_some())
    }

    /// Return `true` if the validation log contains a specific C2PA status
    /// code.
    fn has_status(&self, val: &str) -> bool {
        self.logged_items().iter().any(|vi| {
            if let Some(vs) = &vi.validation_status {
                vs == val
            } else {
                false
            }
        })
    }

    /// Return `true` if the validation log contains a specific error.
    fn has_error<E: Debug>(&self, err: E) -> bool {
        let err_type = format!("{:?}", &err);
        self.logged_items().iter().any(|vi| {
            if let Some(e) = &vi.err_val {
                e == &err_type
            } else {
                false
            }
        })
    }

    /// Keeps track of the current ingredient URI, if any.
    ///
    /// The current URI may be added to any log items that are created.
    fn push_ingredient_uri<S: Into<String>>(&mut self, _uri: S) {}

    /// Removes the current ingredient URI, if any.
    fn pop_ingredient_uri(&mut self) -> Option<String> {
        None
    }
}

pub(crate) mod detailed;
pub(crate) mod one_shot;