Merge "aconfig: create unit test targets for aconfig_protos and aconfig_storage_file crate" into main
This commit is contained in:
@@ -58,6 +58,14 @@
|
|||||||
{
|
{
|
||||||
// printflags unit tests
|
// printflags unit tests
|
||||||
"name": "printflags.test"
|
"name": "printflags.test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// aconfig_protos unit tests
|
||||||
|
"name": "aconfig_protos.test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// aconfig_storage_file unit tests
|
||||||
|
"name": "aconfig_storage_file.test"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -45,12 +45,12 @@ rust_protobuf {
|
|||||||
host_supported: true,
|
host_supported: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
rust_library {
|
rust_defaults {
|
||||||
name: "libaconfig_protos",
|
name: "aconfig_protos.defaults",
|
||||||
|
edition: "2021",
|
||||||
|
clippy_lints: "android",
|
||||||
|
lints: "android",
|
||||||
srcs: ["src/lib.rs"],
|
srcs: ["src/lib.rs"],
|
||||||
crate_name: "aconfig_protos",
|
|
||||||
host_supported: true,
|
|
||||||
lints: "none",
|
|
||||||
rustlibs: [
|
rustlibs: [
|
||||||
"libaconfig_rust_proto",
|
"libaconfig_rust_proto",
|
||||||
"libanyhow",
|
"libanyhow",
|
||||||
@@ -60,3 +60,16 @@ rust_library {
|
|||||||
"libpaste",
|
"libpaste",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rust_library {
|
||||||
|
name: "libaconfig_protos",
|
||||||
|
crate_name: "aconfig_protos",
|
||||||
|
host_supported: true,
|
||||||
|
defaults: ["aconfig_protos.defaults"],
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_test_host {
|
||||||
|
name: "aconfig_protos.test",
|
||||||
|
test_suites: ["general-tests"],
|
||||||
|
defaults: ["aconfig_protos.defaults"],
|
||||||
|
}
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! `aconfig_protos` is a crate for the protos defined for aconfig
|
||||||
// When building with the Android tool-chain
|
// When building with the Android tool-chain
|
||||||
//
|
//
|
||||||
// - an external crate `aconfig_protos` will be generated
|
// - an external crate `aconfig_protos` will be generated
|
||||||
@@ -68,6 +69,7 @@ pub use auto_generated::*;
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
|
|
||||||
|
/// Check if the name identifier is valid
|
||||||
pub fn is_valid_name_ident(s: &str) -> bool {
|
pub fn is_valid_name_ident(s: &str) -> bool {
|
||||||
// Identifiers must match [a-z][a-z0-9_]*, except consecutive underscores are not allowed
|
// Identifiers must match [a-z][a-z0-9_]*, except consecutive underscores are not allowed
|
||||||
if s.contains("__") {
|
if s.contains("__") {
|
||||||
@@ -83,6 +85,7 @@ pub fn is_valid_name_ident(s: &str) -> bool {
|
|||||||
chars.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_')
|
chars.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the package identifier is valid
|
||||||
pub fn is_valid_package_ident(s: &str) -> bool {
|
pub fn is_valid_package_ident(s: &str) -> bool {
|
||||||
if !s.contains('.') {
|
if !s.contains('.') {
|
||||||
return false;
|
return false;
|
||||||
@@ -90,6 +93,7 @@ pub fn is_valid_package_ident(s: &str) -> bool {
|
|||||||
s.split('.').all(is_valid_name_ident)
|
s.split('.').all(is_valid_name_ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the container identifier is valid
|
||||||
pub fn is_valid_container_ident(s: &str) -> bool {
|
pub fn is_valid_container_ident(s: &str) -> bool {
|
||||||
s.split('.').all(is_valid_name_ident)
|
s.split('.').all(is_valid_name_ident)
|
||||||
}
|
}
|
||||||
@@ -111,10 +115,12 @@ macro_rules! ensure_required_fields {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for flag_declaration proto
|
||||||
pub mod flag_declaration {
|
pub mod flag_declaration {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(pdf: &ProtoFlagDeclaration) -> Result<()> {
|
pub fn verify_fields(pdf: &ProtoFlagDeclaration) -> Result<()> {
|
||||||
ensure_required_fields!("flag declaration", pdf, "name", "namespace", "description");
|
ensure_required_fields!("flag declaration", pdf, "name", "namespace", "description");
|
||||||
|
|
||||||
@@ -127,16 +133,19 @@ pub mod flag_declaration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for flag_declarations proto
|
||||||
pub mod flag_declarations {
|
pub mod flag_declarations {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
|
|
||||||
|
/// Construct a proto instance from a textproto string content
|
||||||
pub fn try_from_text_proto(s: &str) -> Result<ProtoFlagDeclarations> {
|
pub fn try_from_text_proto(s: &str) -> Result<ProtoFlagDeclarations> {
|
||||||
let pdf: ProtoFlagDeclarations = super::try_from_text_proto(s)?;
|
let pdf: ProtoFlagDeclarations = super::try_from_text_proto(s)?;
|
||||||
verify_fields(&pdf)?;
|
verify_fields(&pdf)?;
|
||||||
Ok(pdf)
|
Ok(pdf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(pdf: &ProtoFlagDeclarations) -> Result<()> {
|
pub fn verify_fields(pdf: &ProtoFlagDeclarations) -> Result<()> {
|
||||||
ensure_required_fields!("flag declarations", pdf, "package");
|
ensure_required_fields!("flag declarations", pdf, "package");
|
||||||
// TODO(b/312769710): Make the container field required.
|
// TODO(b/312769710): Make the container field required.
|
||||||
@@ -157,10 +166,12 @@ pub mod flag_declarations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for flag_value proto
|
||||||
pub mod flag_value {
|
pub mod flag_value {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(fv: &ProtoFlagValue) -> Result<()> {
|
pub fn verify_fields(fv: &ProtoFlagValue) -> Result<()> {
|
||||||
ensure_required_fields!("flag value", fv, "package", "name", "state", "permission");
|
ensure_required_fields!("flag value", fv, "package", "name", "state", "permission");
|
||||||
|
|
||||||
@@ -171,15 +182,18 @@ pub mod flag_value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for flag_values proto
|
||||||
pub mod flag_values {
|
pub mod flag_values {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
/// Construct a proto instance from a textproto string content
|
||||||
pub fn try_from_text_proto(s: &str) -> Result<ProtoFlagValues> {
|
pub fn try_from_text_proto(s: &str) -> Result<ProtoFlagValues> {
|
||||||
let pfv: ProtoFlagValues = super::try_from_text_proto(s)?;
|
let pfv: ProtoFlagValues = super::try_from_text_proto(s)?;
|
||||||
verify_fields(&pfv)?;
|
verify_fields(&pfv)?;
|
||||||
Ok(pfv)
|
Ok(pfv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(pfv: &ProtoFlagValues) -> Result<()> {
|
pub fn verify_fields(pfv: &ProtoFlagValues) -> Result<()> {
|
||||||
for flag_value in pfv.flag_value.iter() {
|
for flag_value in pfv.flag_value.iter() {
|
||||||
super::flag_value::verify_fields(flag_value)?;
|
super::flag_value::verify_fields(flag_value)?;
|
||||||
@@ -188,10 +202,12 @@ pub mod flag_values {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for flag_permission proto enum
|
||||||
pub mod flag_permission {
|
pub mod flag_permission {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
|
|
||||||
|
/// Construct a flag permission proto enum from string
|
||||||
pub fn parse_from_str(permission: &str) -> Result<ProtoFlagPermission> {
|
pub fn parse_from_str(permission: &str) -> Result<ProtoFlagPermission> {
|
||||||
match permission.to_ascii_lowercase().as_str() {
|
match permission.to_ascii_lowercase().as_str() {
|
||||||
"read_write" => Ok(ProtoFlagPermission::READ_WRITE),
|
"read_write" => Ok(ProtoFlagPermission::READ_WRITE),
|
||||||
@@ -200,6 +216,7 @@ pub mod flag_permission {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serialize flag permission proto enum to string
|
||||||
pub fn to_string(permission: &ProtoFlagPermission) -> &str {
|
pub fn to_string(permission: &ProtoFlagPermission) -> &str {
|
||||||
match permission {
|
match permission {
|
||||||
ProtoFlagPermission::READ_WRITE => "read_write",
|
ProtoFlagPermission::READ_WRITE => "read_write",
|
||||||
@@ -208,10 +225,12 @@ pub mod flag_permission {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for tracepoint proto
|
||||||
pub mod tracepoint {
|
pub mod tracepoint {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(tp: &ProtoTracepoint) -> Result<()> {
|
pub fn verify_fields(tp: &ProtoTracepoint) -> Result<()> {
|
||||||
ensure_required_fields!("tracepoint", tp, "source", "state", "permission");
|
ensure_required_fields!("tracepoint", tp, "source", "state", "permission");
|
||||||
|
|
||||||
@@ -221,10 +240,12 @@ pub mod tracepoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for parsed_flag proto
|
||||||
pub mod parsed_flag {
|
pub mod parsed_flag {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(pf: &ProtoParsedFlag) -> Result<()> {
|
pub fn verify_fields(pf: &ProtoParsedFlag) -> Result<()> {
|
||||||
ensure_required_fields!(
|
ensure_required_fields!(
|
||||||
"parsed flag",
|
"parsed flag",
|
||||||
@@ -265,23 +286,27 @@ pub mod parsed_flag {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the file path of the corresponding flag declaration
|
||||||
pub fn path_to_declaration(pf: &ProtoParsedFlag) -> &str {
|
pub fn path_to_declaration(pf: &ProtoParsedFlag) -> &str {
|
||||||
debug_assert!(!pf.trace.is_empty());
|
debug_assert!(!pf.trace.is_empty());
|
||||||
pf.trace[0].source()
|
pf.trace[0].source()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Utility module for parsed_flags proto
|
||||||
pub mod parsed_flags {
|
pub mod parsed_flags {
|
||||||
use super::*;
|
use super::*;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
/// Construct a proto instance from a binary proto bytes
|
||||||
pub fn try_from_binary_proto(bytes: &[u8]) -> Result<ProtoParsedFlags> {
|
pub fn try_from_binary_proto(bytes: &[u8]) -> Result<ProtoParsedFlags> {
|
||||||
let message: ProtoParsedFlags = protobuf::Message::parse_from_bytes(bytes)?;
|
let message: ProtoParsedFlags = protobuf::Message::parse_from_bytes(bytes)?;
|
||||||
verify_fields(&message)?;
|
verify_fields(&message)?;
|
||||||
Ok(message)
|
Ok(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure the proto instance is valid by checking its fields
|
||||||
pub fn verify_fields(pf: &ProtoParsedFlags) -> Result<()> {
|
pub fn verify_fields(pf: &ProtoParsedFlags) -> Result<()> {
|
||||||
use crate::parsed_flag::path_to_declaration;
|
use crate::parsed_flag::path_to_declaration;
|
||||||
|
|
||||||
@@ -309,6 +334,7 @@ pub mod parsed_flags {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Merge multipe parsed_flags proto
|
||||||
pub fn merge(parsed_flags: Vec<ProtoParsedFlags>, dedup: bool) -> Result<ProtoParsedFlags> {
|
pub fn merge(parsed_flags: Vec<ProtoParsedFlags>, dedup: bool) -> Result<ProtoParsedFlags> {
|
||||||
let mut merged = ProtoParsedFlags::new();
|
let mut merged = ProtoParsedFlags::new();
|
||||||
for mut pfs in parsed_flags.into_iter() {
|
for mut pfs in parsed_flags.into_iter() {
|
||||||
@@ -325,6 +351,7 @@ pub mod parsed_flags {
|
|||||||
Ok(merged)
|
Ok(merged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sort parsed flags
|
||||||
pub fn sort_parsed_flags(pf: &mut ProtoParsedFlags) {
|
pub fn sort_parsed_flags(pf: &mut ProtoParsedFlags) {
|
||||||
pf.parsed_flag.sort_by_key(create_sorting_key);
|
pf.parsed_flag.sort_by_key(create_sorting_key);
|
||||||
}
|
}
|
||||||
@@ -334,7 +361,9 @@ pub mod parsed_flags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ParsedFlagExt trait
|
||||||
pub trait ParsedFlagExt {
|
pub trait ParsedFlagExt {
|
||||||
|
/// Return the fully qualified name
|
||||||
fn fully_qualified_name(&self) -> String;
|
fn fully_qualified_name(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,13 +2,25 @@ package {
|
|||||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||||
}
|
}
|
||||||
|
|
||||||
rust_library {
|
rust_defaults {
|
||||||
name: "libaconfig_storage_file",
|
name: "aconfig_storage_file.defaults",
|
||||||
srcs: ["src/lib.rs"],
|
edition: "2021",
|
||||||
crate_name: "aconfig_storage_file",
|
|
||||||
host_supported: true,
|
|
||||||
lints: "none",
|
lints: "none",
|
||||||
|
srcs: ["src/lib.rs"],
|
||||||
rustlibs: [
|
rustlibs: [
|
||||||
"libanyhow",
|
"libanyhow",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rust_library {
|
||||||
|
name: "libaconfig_storage_file",
|
||||||
|
crate_name: "aconfig_storage_file",
|
||||||
|
host_supported: true,
|
||||||
|
defaults: ["aconfig_storage_file.defaults"],
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_test_host {
|
||||||
|
name: "aconfig_storage_file.test",
|
||||||
|
test_suites: ["general-tests"],
|
||||||
|
defaults: ["aconfig_storage_file.defaults"],
|
||||||
|
}
|
||||||
|
@@ -14,9 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! flag table module defines the flag table file format and methods for serialization
|
||||||
|
//! and deserialization
|
||||||
|
|
||||||
use crate::{read_str_from_bytes, read_u16_from_bytes, read_u32_from_bytes};
|
use crate::{read_str_from_bytes, read_u16_from_bytes, read_u32_from_bytes};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
/// Flag table header struct
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct FlagTableHeader {
|
pub struct FlagTableHeader {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
@@ -28,6 +32,7 @@ pub struct FlagTableHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FlagTableHeader {
|
impl FlagTableHeader {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
result.extend_from_slice(&self.version.to_le_bytes());
|
result.extend_from_slice(&self.version.to_le_bytes());
|
||||||
@@ -41,6 +46,7 @@ impl FlagTableHeader {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
let mut head = 0;
|
let mut head = 0;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -54,6 +60,7 @@ impl FlagTableHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flag table node struct
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
pub struct FlagTableNode {
|
pub struct FlagTableNode {
|
||||||
pub package_id: u32,
|
pub package_id: u32,
|
||||||
@@ -65,6 +72,7 @@ pub struct FlagTableNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FlagTableNode {
|
impl FlagTableNode {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
result.extend_from_slice(&self.package_id.to_le_bytes());
|
result.extend_from_slice(&self.package_id.to_le_bytes());
|
||||||
@@ -77,6 +85,7 @@ impl FlagTableNode {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8], num_buckets: u32) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8], num_buckets: u32) -> Result<Self> {
|
||||||
let mut head = 0;
|
let mut head = 0;
|
||||||
let mut node = Self {
|
let mut node = Self {
|
||||||
@@ -103,7 +112,9 @@ pub struct FlagTable {
|
|||||||
pub nodes: Vec<FlagTableNode>,
|
pub nodes: Vec<FlagTableNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flag table struct
|
||||||
impl FlagTable {
|
impl FlagTable {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
[
|
[
|
||||||
self.header.as_bytes(),
|
self.header.as_bytes(),
|
||||||
@@ -113,6 +124,7 @@ impl FlagTable {
|
|||||||
.concat()
|
.concat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
let header = FlagTableHeader::from_bytes(bytes)?;
|
let header = FlagTableHeader::from_bytes(bytes)?;
|
||||||
let num_flags = header.num_flags;
|
let num_flags = header.num_flags;
|
||||||
|
@@ -14,9 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! flag value module defines the flag value file format and methods for serialization
|
||||||
|
//! and deserialization
|
||||||
|
|
||||||
use crate::{read_str_from_bytes, read_u32_from_bytes, read_u8_from_bytes};
|
use crate::{read_str_from_bytes, read_u32_from_bytes, read_u8_from_bytes};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
/// Flag value header struct
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct FlagValueHeader {
|
pub struct FlagValueHeader {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
@@ -27,6 +31,7 @@ pub struct FlagValueHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FlagValueHeader {
|
impl FlagValueHeader {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
result.extend_from_slice(&self.version.to_le_bytes());
|
result.extend_from_slice(&self.version.to_le_bytes());
|
||||||
@@ -39,6 +44,7 @@ impl FlagValueHeader {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
let mut head = 0;
|
let mut head = 0;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -51,6 +57,7 @@ impl FlagValueHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flag value list struct
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct FlagValueList {
|
pub struct FlagValueList {
|
||||||
pub header: FlagValueHeader,
|
pub header: FlagValueHeader,
|
||||||
@@ -58,6 +65,7 @@ pub struct FlagValueList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FlagValueList {
|
impl FlagValueList {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
[
|
[
|
||||||
self.header.as_bytes(),
|
self.header.as_bytes(),
|
||||||
@@ -66,6 +74,7 @@ impl FlagValueList {
|
|||||||
.concat()
|
.concat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
let header = FlagValueHeader::from_bytes(bytes)?;
|
let header = FlagValueHeader::from_bytes(bytes)?;
|
||||||
let num_flags = header.num_flags;
|
let num_flags = header.num_flags;
|
||||||
|
@@ -14,6 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! `aconfig_storage_file` is a crate that defines aconfig storage file format, it
|
||||||
|
//! also includes apis to read flags from storage files
|
||||||
|
|
||||||
pub mod flag_table;
|
pub mod flag_table;
|
||||||
pub mod flag_value;
|
pub mod flag_value;
|
||||||
pub mod package_table;
|
pub mod package_table;
|
||||||
@@ -26,14 +29,17 @@ pub use crate::flag_table::{FlagTable, FlagTableHeader, FlagTableNode};
|
|||||||
pub use crate::flag_value::{FlagValueHeader, FlagValueList};
|
pub use crate::flag_value::{FlagValueHeader, FlagValueList};
|
||||||
pub use crate::package_table::{PackageTable, PackageTableHeader, PackageTableNode};
|
pub use crate::package_table::{PackageTable, PackageTableHeader, PackageTableNode};
|
||||||
|
|
||||||
|
/// Storage file version
|
||||||
pub const FILE_VERSION: u32 = 1;
|
pub const FILE_VERSION: u32 = 1;
|
||||||
|
|
||||||
|
/// Good hash table prime number
|
||||||
pub const HASH_PRIMES: [u32; 29] = [
|
pub const HASH_PRIMES: [u32; 29] = [
|
||||||
7, 17, 29, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241,
|
7, 17, 29, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241,
|
||||||
786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611,
|
786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611,
|
||||||
402653189, 805306457, 1610612741,
|
402653189, 805306457, 1610612741,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Storage file type enum
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum StorageFileSelection {
|
pub enum StorageFileSelection {
|
||||||
PackageMap,
|
PackageMap,
|
||||||
|
@@ -14,9 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//! package table module defines the package table file format and methods for serialization
|
||||||
|
//! and deserialization
|
||||||
|
|
||||||
use crate::{read_str_from_bytes, read_u32_from_bytes};
|
use crate::{read_str_from_bytes, read_u32_from_bytes};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
/// Package table header struct
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct PackageTableHeader {
|
pub struct PackageTableHeader {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
@@ -28,6 +32,7 @@ pub struct PackageTableHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PackageTableHeader {
|
impl PackageTableHeader {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
result.extend_from_slice(&self.version.to_le_bytes());
|
result.extend_from_slice(&self.version.to_le_bytes());
|
||||||
@@ -41,6 +46,7 @@ impl PackageTableHeader {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
let mut head = 0;
|
let mut head = 0;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -54,6 +60,7 @@ impl PackageTableHeader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Package table node struct
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct PackageTableNode {
|
pub struct PackageTableNode {
|
||||||
pub package_name: String,
|
pub package_name: String,
|
||||||
@@ -66,6 +73,7 @@ pub struct PackageTableNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PackageTableNode {
|
impl PackageTableNode {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
let name_bytes = self.package_name.as_bytes();
|
let name_bytes = self.package_name.as_bytes();
|
||||||
@@ -77,6 +85,7 @@ impl PackageTableNode {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8], num_buckets: u32) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8], num_buckets: u32) -> Result<Self> {
|
||||||
let mut head = 0;
|
let mut head = 0;
|
||||||
let mut node = Self {
|
let mut node = Self {
|
||||||
@@ -94,6 +103,7 @@ impl PackageTableNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Package table struct
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct PackageTable {
|
pub struct PackageTable {
|
||||||
pub header: PackageTableHeader,
|
pub header: PackageTableHeader,
|
||||||
@@ -102,6 +112,7 @@ pub struct PackageTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PackageTable {
|
impl PackageTable {
|
||||||
|
/// Serialize to bytes
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
[
|
[
|
||||||
self.header.as_bytes(),
|
self.header.as_bytes(),
|
||||||
@@ -111,6 +122,7 @@ impl PackageTable {
|
|||||||
.concat()
|
.concat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize from bytes
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||||
let header = PackageTableHeader::from_bytes(bytes)?;
|
let header = PackageTableHeader::from_bytes(bytes)?;
|
||||||
let num_packages = header.num_packages;
|
let num_packages = header.num_packages;
|
||||||
|
Reference in New Issue
Block a user