feat: implement suggest command to channel

This commit is contained in:
Dmitriy Pleshevskiy 2020-07-23 14:07:38 +03:00
parent ed0fef1956
commit b24ad5a402
5 changed files with 77 additions and 6 deletions

View file

@ -204,6 +204,19 @@ impl SonicChannel {
limit: Option<usize>, limit: Option<usize>,
offset: Option<usize>, offset: Option<usize>,
); );
use SuggestCommand for fn suggest<'a>(
collection: &'a str,
bucket: &'a str,
word: &'a str,
);
use SuggestCommand for fn suggest_with_limit<'a>(
collection: &'a str,
bucket: &'a str,
word: &'a str,
limit: Option<usize>,
);
} }
#[cfg(feature = "control")] #[cfg(feature = "control")]

0
src/commands/flush.rs Normal file
View file

View file

@ -7,6 +7,8 @@ mod ping;
mod push; mod push;
#[cfg(feature = "search")] #[cfg(feature = "search")]
mod query; mod query;
#[cfg(feature = "search")]
mod suggest;
pub use quit::QuitCommand; pub use quit::QuitCommand;
pub use start::StartCommand; pub use start::StartCommand;
@ -16,6 +18,8 @@ pub use ping::PingCommand;
pub use push::PushCommand; pub use push::PushCommand;
#[cfg(feature = "search")] #[cfg(feature = "search")]
pub use query::QueryCommand; pub use query::QueryCommand;
#[cfg(feature = "search")]
pub use suggest::SuggestCommand;
use crate::result::Result; use crate::result::Result;

View file

@ -55,12 +55,7 @@ impl StreamCommand for QueryCommand<'_> {
} else if caps["objects"].is_empty() { } else if caps["objects"].is_empty() {
Ok(vec![]) Ok(vec![])
} else { } else {
let objects = caps["objects"] Ok(caps["objects"].split(" ").map(str::to_owned).collect())
.split(" ")
.map(String::from)
.collect::<Vec<String>>();
Ok(objects)
} }
} }
} }

59
src/commands/suggest.rs Normal file
View file

@ -0,0 +1,59 @@
use super::StreamCommand;
use crate::result::*;
use regex::Regex;
const RE_SUGGEST_RECEIVED_MESSAGE: &str = r"(?x)
^PENDING\s(?P<pending_suggest_id>\w+)\r\n
EVENT\sSUGGEST\s(?P<event_suggest_id>\w+)\s(?P<words>.*?)\r\n$
";
#[derive(Debug, Default)]
pub struct SuggestCommand<'a> {
pub collection: &'a str,
pub bucket: &'a str,
pub word: &'a str,
pub limit: Option<usize>,
}
impl StreamCommand for SuggestCommand<'_> {
type Response = Vec<String>;
const READ_LINES_COUNT: usize = 2;
fn message(&self) -> String {
let mut message = format!(
r#"SUGGEST {} {} "{}""#,
self.collection, self.bucket, self.word
);
if let Some(limit) = self.limit.as_ref() {
message.push_str(&format!(" LIMIT({})", limit));
}
message.push_str("\r\n");
message
}
fn receive(&self, message: String) -> Result<Self::Response> {
lazy_static! {
static ref RE: Regex = Regex::new(RE_SUGGEST_RECEIVED_MESSAGE).unwrap();
}
dbg!(&message);
match RE.captures(&message) {
None => Err(Error::new(ErrorKind::QueryResponseError(
"Sonic response are wrong. Please write issue to github.",
))),
Some(caps) => {
if &caps["pending_suggest_id"] != &caps["event_suggest_id"] {
Err(Error::new(ErrorKind::QueryResponseError(
"Pending id and event id don't match",
)))
} else if caps["words"].is_empty() {
Ok(vec![])
} else {
Ok(caps["words"].split(" ").map(str::to_owned).collect())
}
}
}
}
}