aconfig: modify_parsed_flags_based_on_mode return Result

This commit changes modify_parsed_flags_based_on_mode to return Result
instead of vector. This change will have two consequences.
1. Error will be thrown if no flags fit into the current codegen mode
2. Error will be thrown if the flag declaration is empty

Bug: 311152507
Test: atest aconfig.test
Change-Id: I69b9a84312faed9f757bf3974b3cea49c5c5e285
diff --git a/tools/aconfig/src/codegen/cpp.rs b/tools/aconfig/src/codegen/cpp.rs
index 06e5cca..d6bebba 100644
--- a/tools/aconfig/src/codegen/cpp.rs
+++ b/tools/aconfig/src/codegen/cpp.rs
@@ -1028,7 +1028,7 @@
         expected_src: &str,
     ) {
         let modified_parsed_flags =
-            crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode);
+            crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
         let generated =
             generate_cpp_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
                 .unwrap();
diff --git a/tools/aconfig/src/codegen/mod.rs b/tools/aconfig/src/codegen/mod.rs
index fc61b7b..476d2b3 100644
--- a/tools/aconfig/src/codegen/mod.rs
+++ b/tools/aconfig/src/codegen/mod.rs
@@ -55,9 +55,19 @@
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
 pub enum CodegenMode {
+    Exported,
     Production,
     Test,
-    Exported,
+}
+
+impl std::fmt::Display for CodegenMode {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        match self {
+            CodegenMode::Exported => write!(f, "exported"),
+            CodegenMode::Production => write!(f, "production"),
+            CodegenMode::Test => write!(f, "test"),
+        }
+    }
 }
 
 #[cfg(test)]
diff --git a/tools/aconfig/src/codegen/rust.rs b/tools/aconfig/src/codegen/rust.rs
index 6cf0b32..56cb311 100644
--- a/tools/aconfig/src/codegen/rust.rs
+++ b/tools/aconfig/src/codegen/rust.rs
@@ -557,7 +557,7 @@
     fn test_generate_rust_code(mode: CodegenMode) {
         let parsed_flags = crate::test::parse_test_flags();
         let modified_parsed_flags =
-            crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode);
+            crate::commands::modify_parsed_flags_based_on_mode(parsed_flags, mode).unwrap();
         let generated =
             generate_rust_code(crate::test::TEST_PACKAGE, modified_parsed_flags.into_iter(), mode)
                 .unwrap();
diff --git a/tools/aconfig/src/commands.rs b/tools/aconfig/src/commands.rs
index 23667bb..7d9dd69 100644
--- a/tools/aconfig/src/commands.rs
+++ b/tools/aconfig/src/commands.rs
@@ -200,7 +200,7 @@
 
 pub fn create_cpp_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<Vec<OutputFile>> {
     let parsed_flags = input.try_parse_flags()?;
-    let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode);
+    let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode)?;
     let Some(package) = find_unique_package(&modified_parsed_flags) else {
         bail!("no parsed flags, or the parsed flags use different packages");
     };
@@ -210,7 +210,7 @@
 
 pub fn create_rust_lib(mut input: Input, codegen_mode: CodegenMode) -> Result<OutputFile> {
     let parsed_flags = input.try_parse_flags()?;
-    let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode);
+    let modified_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, codegen_mode)?;
     let Some(package) = find_unique_package(&modified_parsed_flags) else {
         bail!("no parsed flags, or the parsed flags use different packages");
     };
@@ -331,7 +331,7 @@
 pub fn modify_parsed_flags_based_on_mode(
     parsed_flags: ProtoParsedFlags,
     codegen_mode: CodegenMode,
-) -> Vec<ProtoParsedFlag> {
+) -> Result<Vec<ProtoParsedFlag>> {
     fn exported_mode_flag_modifier(mut parsed_flag: ProtoParsedFlag) -> ProtoParsedFlag {
         parsed_flag.set_state(ProtoFlagState::DISABLED);
         parsed_flag.set_permission(ProtoFlagPermission::READ_WRITE);
@@ -339,7 +339,7 @@
         parsed_flag
     }
 
-    match codegen_mode {
+    let modified_parsed_flags: Vec<_> = match codegen_mode {
         CodegenMode::Exported => parsed_flags
             .parsed_flag
             .into_iter()
@@ -349,7 +349,12 @@
         CodegenMode::Production | CodegenMode::Test => {
             parsed_flags.parsed_flag.into_iter().collect()
         }
+    };
+    if modified_parsed_flags.is_empty() {
+        bail!("{} library contains no exported flags.", codegen_mode);
     }
+
+    Ok(modified_parsed_flags)
 }
 
 #[cfg(test)]
@@ -652,7 +657,8 @@
     fn test_modify_parsed_flags_based_on_mode_prod() {
         let parsed_flags = crate::test::parse_test_flags();
         let p_parsed_flags =
-            modify_parsed_flags_based_on_mode(parsed_flags.clone(), CodegenMode::Production);
+            modify_parsed_flags_based_on_mode(parsed_flags.clone(), CodegenMode::Production)
+                .unwrap();
         assert_eq!(parsed_flags.parsed_flag.len(), p_parsed_flags.len());
         for (i, item) in p_parsed_flags.iter().enumerate() {
             assert!(parsed_flags.parsed_flag[i].eq(item));
@@ -662,7 +668,8 @@
     #[test]
     fn test_modify_parsed_flags_based_on_mode_exported() {
         let parsed_flags = crate::test::parse_test_flags();
-        let p_parsed_flags = modify_parsed_flags_based_on_mode(parsed_flags, CodegenMode::Exported);
+        let p_parsed_flags =
+            modify_parsed_flags_based_on_mode(parsed_flags, CodegenMode::Exported).unwrap();
         assert_eq!(3, p_parsed_flags.len());
         for flag in p_parsed_flags.iter() {
             assert_eq!(ProtoFlagState::DISABLED, flag.state());
@@ -670,5 +677,14 @@
             assert!(!flag.is_fixed_read_only());
             assert!(flag.is_exported());
         }
+
+        let mut parsed_flags = crate::test::parse_test_flags();
+        parsed_flags.parsed_flag.retain_mut(|pf| !pf.is_exported());
+        let error =
+            modify_parsed_flags_based_on_mode(parsed_flags, CodegenMode::Exported).unwrap_err();
+        assert_eq!(
+            format!("{} library contains no exported flags.", CodegenMode::Exported),
+            format!("{:?}", error)
+        );
     }
 }