diff --git a/src/channel.rs b/src/channel.rs index d1f29c5..50b156d 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -204,6 +204,19 @@ impl SonicChannel { limit: Option, offset: Option, ); + + 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, + ); } #[cfg(feature = "control")] diff --git a/src/commands/flush.rs b/src/commands/flush.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 6226a89..4c82d7d 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -7,6 +7,8 @@ mod ping; mod push; #[cfg(feature = "search")] mod query; +#[cfg(feature = "search")] +mod suggest; pub use quit::QuitCommand; pub use start::StartCommand; @@ -16,6 +18,8 @@ pub use ping::PingCommand; pub use push::PushCommand; #[cfg(feature = "search")] pub use query::QueryCommand; +#[cfg(feature = "search")] +pub use suggest::SuggestCommand; use crate::result::Result; diff --git a/src/commands/query.rs b/src/commands/query.rs index a99af8a..410b2b0 100644 --- a/src/commands/query.rs +++ b/src/commands/query.rs @@ -55,12 +55,7 @@ impl StreamCommand for QueryCommand<'_> { } else if caps["objects"].is_empty() { Ok(vec![]) } else { - let objects = caps["objects"] - .split(" ") - .map(String::from) - .collect::>(); - - Ok(objects) + Ok(caps["objects"].split(" ").map(str::to_owned).collect()) } } } diff --git a/src/commands/suggest.rs b/src/commands/suggest.rs new file mode 100644 index 0000000..ea14dbc --- /dev/null +++ b/src/commands/suggest.rs @@ -0,0 +1,59 @@ +use super::StreamCommand; +use crate::result::*; +use regex::Regex; + +const RE_SUGGEST_RECEIVED_MESSAGE: &str = r"(?x) + ^PENDING\s(?P\w+)\r\n + EVENT\sSUGGEST\s(?P\w+)\s(?P.*?)\r\n$ +"; + +#[derive(Debug, Default)] +pub struct SuggestCommand<'a> { + pub collection: &'a str, + pub bucket: &'a str, + pub word: &'a str, + pub limit: Option, +} + +impl StreamCommand for SuggestCommand<'_> { + type Response = Vec; + + 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 { + 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()) + } + } + } + } +}