ieql/output/output.rs
1//! This file provides functionality related to outputs.
2
3use common::pattern::PatternMatch;
4use input::document::CompiledDocument;
5use query::query::CompiledQuery;
6use query::response::{ResponseItem, ResponseKind};
7
8/// `Output` represents a 'match' of a Query. It is the primary
9/// product of an IEQL scan, and contains many variable (and configurable)
10/// pieces of data and metadata.
11///
12/// _Note: `response` and `output` are synonymous in the context of this
13/// documentation._
14///
15/// Outputs have two kinds: `Full` and `Partial`. Full outputs are for
16/// matches which exist on their own—for example, a match of someone's
17/// name online. Partial outputs, however, are meant to be MapReduced.
18/// For example, if a linguist wanted to count the number of times a certain
19/// word appears online, they would configure their query to produce a `Partial`
20/// response, which they would then MapReduce.
21///
22/// There is not currently full support for partial IEQL outputs.
23#[derive(Serialize, Deserialize, Debug, PartialEq)]
24pub struct Output {
25 /// Contains the data relevant for the user; for example, excerpts of the match.
26 pub items: Vec<OutputItem>,
27 /// Represents the _kind_ of the output (`Full` or `Partial`).
28 pub kind: OutputKind,
29 /// This is an optional value for identifying the output, and can vary
30 /// based on your implementation. In most cases, when present, this
31 /// is some form of UUID.
32 pub id: Option<String>,
33 /// This is the ID of the query that created the output. Note that this
34 /// will only be present when the query that created the output itself
35 /// has an id.
36 pub query_id: Option<String>,
37}
38
39/// This enum specifies the output type of the query. For more information
40/// about each type of query, please see the specification.
41///
42/// **There is currently not full support for partial queries.**
43#[derive(Serialize, Deserialize, Debug, PartialEq)]
44pub enum OutputKind {
45 Full,
46 Partial,
47}
48
49/// This enum represents a possible output item. `OutputItem`s are typically
50/// user-meaningful, and are not machine readable. The items included in the
51/// output are dependent on the `response` configuration of the query.
52///
53/// Much of this information is simply copied from the metadata of the document
54/// that produced it.
55#[derive(Serialize, Deserialize, Debug, PartialEq)]
56pub enum OutputItem {
57 /// Represents the URL of the document that matched the query, if present.
58 /// There is _no guarantee_ that this will be a valid url; if the mechanism
59 /// by which documents are loaded provides a faulty or invalid URL (such as
60 /// a local filepath, as the command line interface does when loading documents),
61 /// this URL will be unchanged.
62 Url(Option<String>),
63 /// Represents a valid IETF MIME type, as per RFC 2045.
64 Mime(Option<String>),
65 /// Represents the domain (or hostname) of the `Url`. When the URL is not present, neither
66 /// will the domain be.
67 Domain(Option<String>),
68 /// Contains any number of `PatternMatch`es—in other words, excerpts.
69 Excerpt(Vec<PatternMatch>),
70 /// Contains the full content of the matched page
71 FullContent(Option<String>)
72}
73
74/// Represents a batch (collection) of outputs. This function tends to be
75/// helpful for multiprocessing, though it is somewhat infrequently used.
76#[derive(Serialize, Deserialize, Debug, PartialEq)]
77pub struct OutputBatch {
78 /// Contains the outputs.
79 pub outputs: Vec<Output>,
80}
81
82impl From<Vec<Output>> for OutputBatch {
83 fn from(outputs: Vec<Output>) -> OutputBatch {
84 OutputBatch { outputs: outputs }
85 }
86}
87
88fn string_clone_helper(to_clone: &Option<String>) -> Option<String> {
89 match to_clone {
90 Some(value) => Some(value.clone()),
91 None => None,
92 }
93}
94
95impl Output {
96 /// Create a new output from the given data. Please note that this
97 /// operation is **expensive**!
98 ///
99 /// # Arguments
100 /// * `document`: the compiled document that the query matched
101 /// * `query`: the compiled query that matched the document
102 /// * `matches`: the `PatternMatch`es produced by the queries' triggers
103 /// * `id`: the optional ID of the desired output
104 pub fn new(
105 document: &CompiledDocument,
106 query: &CompiledQuery,
107 matches: Vec<PatternMatch>,
108 id: Option<String>,
109 ) -> Output {
110 // warning: expensive!
111 let kind = match query.response.kind {
112 ResponseKind::Full => OutputKind::Full,
113 ResponseKind::Partial => OutputKind::Partial,
114 };
115 let query_id = string_clone_helper(&query.id);
116 let mut items: Vec<OutputItem> = Vec::new();
117 for item in &query.response.include {
118 match item {
119 ResponseItem::Domain => items.push(OutputItem::Domain((&document.domain).clone())),
120 ResponseItem::Mime => {
121 items.push(OutputItem::Mime(string_clone_helper(&document.mime)))
122 }
123 ResponseItem::Url => {
124 items.push(OutputItem::Url(string_clone_helper(&document.url)))
125 }
126 ResponseItem::Excerpt => items.push(OutputItem::Excerpt(matches.clone())),
127 ResponseItem::FullContent => items.push(OutputItem::FullContent(Some((&document.raw).clone())))
128 }
129 }
130 Output {
131 items: items,
132 kind: kind,
133 id: id,
134 query_id: query_id,
135 }
136 }
137}
138
139impl OutputBatch {
140 /// Merges the output batch with the other output
141 /// batch. This function _consumes_ the other output
142 /// batch, but involves no memory duplication.
143 pub fn merge_with(&mut self, other: OutputBatch) {
144 self.outputs.extend(other.outputs);
145 }
146
147 /// Create a new empty output batch.
148 pub fn new() -> OutputBatch {
149 OutputBatch::from(vec![])
150 }
151}
152
153impl std::fmt::Display for Output {
154 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
155 let id = match &self.id {
156 Some(value) => format!("[{}]", value),
157 None => String::from(""),
158 };
159 let kind = match self.kind {
160 OutputKind::Full => "full response",
161 OutputKind::Partial => "partial response",
162 };
163 let query_id = match &self.query_id {
164 Some(value) => format!(" from `{}`", value),
165 None => String::from(""),
166 };
167 let mut items: Vec<String> = Vec::new();
168 for item in &self.items {
169 items.push(format!("{:?}", item));
170 }
171 write!(f, "{} {}{}: {:?}", id, kind, query_id, items)
172 }}