blob: 76b853b40571f5a53bcc4b655e1d9e9b3079a1e7 [file] [log] [blame]
Mårten Kongstad4d2b4b02023-04-27 16:05:58 +02001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use anyhow::{Context, Result};
18use clap::ValueEnum;
19use serde::{Deserialize, Serialize};
20use std::fmt;
21use std::io::Read;
22
23use crate::aconfig::{Flag, Override};
24use crate::cache::Cache;
25
26#[derive(Clone, Serialize, Deserialize)]
27pub enum Source {
28 #[allow(dead_code)] // only used in unit tests
29 Memory,
30 File(String),
31}
32
33impl fmt::Display for Source {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 match self {
36 Self::Memory => write!(f, "<memory>"),
37 Self::File(path) => write!(f, "{}", path),
38 }
39 }
40}
41
42pub struct Input {
43 pub source: Source,
44 pub reader: Box<dyn Read>,
45}
46
Mårten Kongstad09c28d12023-05-04 13:29:26 +020047pub fn create_cache(build_id: u32, aconfigs: Vec<Input>, overrides: Vec<Input>) -> Result<Cache> {
48 let mut cache = Cache::new(build_id);
Mårten Kongstad4d2b4b02023-04-27 16:05:58 +020049
50 for mut input in aconfigs {
51 let mut contents = String::new();
52 input.reader.read_to_string(&mut contents)?;
53 let flags = Flag::try_from_text_proto_list(&contents)
54 .with_context(|| format!("Failed to parse {}", input.source))?;
55 for flag in flags {
56 cache.add_flag(input.source.clone(), flag)?;
57 }
58 }
59
60 for mut input in overrides {
61 let mut contents = String::new();
62 input.reader.read_to_string(&mut contents)?;
63 let overrides = Override::try_from_text_proto_list(&contents)
64 .with_context(|| format!("Failed to parse {}", input.source))?;
65 for override_ in overrides {
66 cache.add_override(input.source.clone(), override_)?;
67 }
68 }
69
70 Ok(cache)
71}
72
73#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
74pub enum Format {
75 Text,
76 Debug,
77}
78
79pub fn dump_cache(cache: Cache, format: Format) -> Result<()> {
80 match format {
81 Format::Text => {
82 for item in cache.iter() {
Mårten Kongstad09c28d12023-05-04 13:29:26 +020083 println!("{}: {}", item.id, item.value);
Mårten Kongstad4d2b4b02023-04-27 16:05:58 +020084 }
85 }
86 Format::Debug => {
87 for item in cache.iter() {
Mårten Kongstad09c28d12023-05-04 13:29:26 +020088 println!("{}: {} ({:?})", item.id, item.value, item.debug);
Mårten Kongstad4d2b4b02023-04-27 16:05:58 +020089 }
90 }
91 }
92 Ok(())
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_create_cache() {
101 let s = r#"
102 flag {
103 id: "a"
104 description: "Description of a"
Mårten Kongstad09c28d12023-05-04 13:29:26 +0200105 value {
106 value: true
107 }
Mårten Kongstad4d2b4b02023-04-27 16:05:58 +0200108 }
109 "#;
110 let aconfigs = vec![Input { source: Source::Memory, reader: Box::new(s.as_bytes()) }];
111 let o = r#"
112 override {
113 id: "a"
114 value: false
115 }
116 "#;
117 let overrides = vec![Input { source: Source::Memory, reader: Box::new(o.as_bytes()) }];
Mårten Kongstad09c28d12023-05-04 13:29:26 +0200118 let cache = create_cache(1, aconfigs, overrides).unwrap();
119 let value = cache.iter().find(|&item| item.id == "a").unwrap().value;
Mårten Kongstad4d2b4b02023-04-27 16:05:58 +0200120 assert!(!value);
121 }
122}