blob: 27c8628eb755660b5f374f837b5f42f1d44e4d47 [file] [log] [blame]
Jiyong Parkf4883fc2023-08-10 14:37:46 +09001// Copyright 2023, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Provides random utilities for components in AVF
16
17use log::error;
18use std::fmt::Debug;
19
20/// Convenient trait for logging an error while returning it
21pub trait LogResult<T, E> {
22 /// If this is `Err`, the error is debug-formatted and is logged via `error!`.
23 fn with_log(self) -> Result<T, E>;
24}
25
26impl<T, E: Debug> LogResult<T, E> for Result<T, E> {
27 fn with_log(self) -> Result<T, E> {
28 self.map_err(|e| {
29 error!("{e:?}");
30 e
31 })
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38 use log::{LevelFilter, Log, Metadata, Record};
39 use std::cell::RefCell;
40 use std::io::{Error, ErrorKind};
41
42 struct TestLogger {
43 last_log: RefCell<String>,
44 }
45 static TEST_LOGGER: TestLogger = TestLogger { last_log: RefCell::new(String::new()) };
46
47 // SAFETY: TestLogger is used only inside the test which is single-treaded.
48 unsafe impl Sync for TestLogger {}
49
50 impl Log for TestLogger {
51 fn enabled(&self, _metadata: &Metadata) -> bool {
52 true
53 }
54 fn log(&self, record: &Record) {
55 *self.last_log.borrow_mut() = format!("{}", record.args());
56 }
57 fn flush(&self) {}
58 }
59
60 #[test]
61 fn test_logresult_emits_error_log() {
62 log::set_logger(&TEST_LOGGER).unwrap();
63 log::set_max_level(LevelFilter::Info);
64
65 let e = Error::from(ErrorKind::NotFound);
66 let res: Result<(), Error> = Err(e).with_log();
67
68 assert!(res.is_err());
69 assert_eq!(TEST_LOGGER.last_log.borrow().as_str(), "Kind(NotFound)");
70 }
71}