Add tests that cover all of request payload types

pull/189/head
Chip Senkbeil 1 year ago
parent 777e026bfc
commit 810567b5e9
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

@ -1,21 +1,26 @@
use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use crate::utils;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default, deny_unknown_fields, rename_all = "snake_case")]
pub struct SetPermissionsOptions {
/// Whether or not to exclude symlinks from traversal entirely, meaning that permissions will
/// not be set on symlinks (usually resolving the symlink and setting the permission of the
/// referenced file or directory) that are explicitly provided or show up during recursion.
#[serde(skip_serializing_if = "utils::is_false")]
pub exclude_symlinks: bool,
/// Whether or not to traverse symlinks when recursively setting permissions. Note that this
/// does NOT influence setting permissions when encountering a symlink as most platforms will
/// resolve the symlink before setting permissions.
#[serde(skip_serializing_if = "utils::is_false")]
pub follow_symlinks: bool,
/// Whether or not to set the permissions of the file hierarchies rooted in the paths, instead
/// of just the paths themselves.
#[serde(skip_serializing_if = "utils::is_false")]
pub recursive: bool,
}

@ -6,6 +6,7 @@ use std::str::FromStr;
use serde::{Deserialize, Serialize};
use crate::common::FileType;
use crate::utils;
/// Id associated with a search
pub type SearchId = u32;
@ -27,6 +28,44 @@ pub struct SearchQuery {
pub options: SearchQueryOptions,
}
impl SearchQuery {
/// Creates a search query targeting the contents of files.
pub fn contents<I, T>(
condition: SearchQueryCondition,
paths: I,
options: SearchQueryOptions,
) -> Self
where
I: IntoIterator<Item = T>,
T: Into<PathBuf>,
{
Self {
target: SearchQueryTarget::Contents,
condition,
paths: paths.into_iter().map(Into::into).collect(),
options,
}
}
/// Creates a search query targeting the paths of files, directories, and symlinks.
pub fn path<I, T>(
condition: SearchQueryCondition,
paths: I,
options: SearchQueryOptions,
) -> Self
where
I: IntoIterator<Item = T>,
T: Into<PathBuf>,
{
Self {
target: SearchQueryTarget::Path,
condition,
paths: paths.into_iter().map(Into::into).collect(),
options,
}
}
}
/// Kind of data to examine using conditions
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
@ -144,6 +183,7 @@ impl FromStr for SearchQueryCondition {
#[serde(default)]
pub struct SearchQueryOptions {
/// Restrict search to only these file types (otherwise all are allowed).
#[serde(skip_serializing_if = "HashSet::is_empty")]
pub allowed_file_types: HashSet<FileType>,
/// Regex to use to filter paths being searched to only those that match the include condition.
@ -164,9 +204,11 @@ pub struct SearchQueryOptions {
///
/// An upward search will ALWAYS search the contents of a directory, so this means providing a
/// path to a directory will search its entries EVEN if the max_depth is 0.
#[serde(skip_serializing_if = "utils::is_false")]
pub upward: bool,
/// Search should follow symbolic links.
#[serde(skip_serializing_if = "utils::is_false")]
pub follow_symbolic_links: bool,
/// Maximum results to return before stopping the query.
@ -325,11 +367,7 @@ mod tests {
"value": "hello world",
},
"paths": ["path1", "path2"],
"options": {
"allowed_file_types": [],
"upward": false,
"follow_symbolic_links": false,
},
"options": {},
})
);
}
@ -343,11 +381,6 @@ mod tests {
"value": "hello world",
},
"paths": ["path1", "path2"],
"options": {
"allowed_file_types": [],
"upward": false,
"follow_symbolic_links": false,
},
});
let query: SearchQuery = serde_json::from_value(value).unwrap();
@ -864,14 +897,7 @@ mod tests {
};
let value = serde_json::to_value(options).unwrap();
assert_eq!(
value,
serde_json::json!({
"allowed_file_types": [],
"upward": false,
"follow_symbolic_links": false,
})
);
assert_eq!(value, serde_json::json!({}));
}
#[test]
@ -915,11 +941,7 @@ mod tests {
#[test]
fn should_be_able_to_deserialize_minimal_options_from_json() {
let value = serde_json::json!({
"allowed_file_types": [],
"upward": false,
"follow_symbolic_links": false,
});
let value = serde_json::json!({});
let options: SearchQueryOptions = serde_json::from_value(value).unwrap();
assert_eq!(

@ -8,3 +8,10 @@ pub use common::*;
pub use msg::*;
pub use request::*;
pub use response::*;
/// Protocol version indicated by the tuple of (major, minor, patch).
///
/// This is different from the crate version, which matches that of the complete suite of distant
/// crates. Rather, this verison is used to provide stability indicators when the protocol itself
/// changes across crate versions.
pub const VERSION: (u8, u8, u8) = (0, 1, 0);

File diff suppressed because it is too large Load Diff

@ -126,6 +126,7 @@ pub enum Response {
success: bool,
/// Exit code associated with termination, will be missing if terminated by signal
#[serde(default, skip_serializing_if = "Option::is_none")]
code: Option<i32>,
},

@ -1,5 +1,23 @@
use serde::{Deserialize, Serialize};
/// Used purely for skipping serialization of values that are false by default.
#[inline]
pub const fn is_false(value: &bool) -> bool {
!*value
}
/// Used purely for skipping serialization of values that are 1 by default.
#[inline]
pub const fn is_one(value: &usize) -> bool {
*value == 1
}
/// Used to provide a default serde value of 1.
#[inline]
pub const fn one() -> usize {
1
}
pub fn deserialize_u128_option<'de, D>(deserializer: D) -> Result<Option<u128>, D::Error>
where
D: serde::Deserializer<'de>,

Loading…
Cancel
Save