1use std::convert::TryInto;
5use std::error::Error as StdError;
6use std::fmt;
7
8use indradb::ValidationError;
9use serde_json::Error as SerdeJsonError;
10use uuid::Error as UuidError;
11use uuid::Uuid;
12
13#[derive(Debug)]
15pub enum ConversionError {
16 Json { inner: SerdeJsonError },
17 Uuid { inner: UuidError },
18 Validation { inner: ValidationError },
19 NoneField { name: String },
20 UnexpectedResponseType,
21}
22
23impl StdError for ConversionError {
24 fn source(&self) -> Option<&(dyn StdError + 'static)> {
25 match *self {
26 ConversionError::Json { ref inner } => Some(inner),
27 ConversionError::Uuid { ref inner } => Some(inner),
28 ConversionError::Validation { ref inner } => Some(inner),
29 _ => None,
30 }
31 }
32}
33
34impl fmt::Display for ConversionError {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 match *self {
37 ConversionError::Json { ref inner } => write!(f, "json conversion failed: {inner}"),
38 ConversionError::Uuid { ref inner } => write!(f, "uuid conversion failed: {inner}"),
39 ConversionError::Validation { ref inner } => write!(f, "validation conversion failed: {inner}"),
40 ConversionError::NoneField { ref name } => write!(f, "proto field '{name}' should not be none"),
41 ConversionError::UnexpectedResponseType => write!(f, "unexpected response type"),
42 }
43 }
44}
45
46impl From<SerdeJsonError> for ConversionError {
47 fn from(err: SerdeJsonError) -> Self {
48 ConversionError::Json { inner: err }
49 }
50}
51
52impl From<UuidError> for ConversionError {
53 fn from(err: UuidError) -> Self {
54 ConversionError::Uuid { inner: err }
55 }
56}
57
58impl From<ValidationError> for ConversionError {
59 fn from(err: ValidationError) -> Self {
60 ConversionError::Validation { inner: err }
61 }
62}
63
64fn required_field<T>(field_name: &str, value: Option<T>) -> Result<T, ConversionError> {
65 value.ok_or_else(|| ConversionError::NoneField {
66 name: field_name.to_string(),
67 })
68}
69
70impl From<Uuid> for crate::Uuid {
71 fn from(uuid: Uuid) -> Self {
72 crate::Uuid {
73 value: uuid.as_bytes().to_vec(),
74 }
75 }
76}
77
78impl TryInto<Uuid> for crate::Uuid {
79 type Error = ConversionError;
80
81 fn try_into(self) -> Result<Uuid, Self::Error> {
82 Ok(Uuid::from_slice(&self.value)?)
83 }
84}
85
86impl From<indradb::Identifier> for crate::Identifier {
87 fn from(t: indradb::Identifier) -> Self {
88 crate::Identifier { value: t.to_string() }
89 }
90}
91
92impl TryInto<indradb::Identifier> for crate::Identifier {
93 type Error = ConversionError;
94
95 fn try_into(self) -> Result<indradb::Identifier, Self::Error> {
96 Ok(indradb::Identifier::new(self.value)?)
97 }
98}
99
100impl From<indradb::Json> for crate::Json {
101 fn from(value: indradb::Json) -> Self {
102 crate::Json {
103 value: (*value).to_string(),
104 }
105 }
106}
107
108impl TryInto<indradb::Json> for crate::Json {
109 type Error = ConversionError;
110
111 fn try_into(self) -> Result<indradb::Json, Self::Error> {
112 Ok(serde_json::from_str(&self.value)?)
113 }
114}
115
116impl From<indradb::Edge> for crate::Edge {
117 fn from(edge: indradb::Edge) -> Self {
118 crate::Edge {
119 outbound_id: Some(edge.outbound_id.into()),
120 t: Some(edge.t.into()),
121 inbound_id: Some(edge.inbound_id.into()),
122 }
123 }
124}
125
126impl TryInto<indradb::Edge> for crate::Edge {
127 type Error = ConversionError;
128
129 fn try_into(self) -> Result<indradb::Edge, Self::Error> {
130 Ok(indradb::Edge::new(
131 required_field("outbound_id", self.outbound_id)?.try_into()?,
132 required_field("t", self.t)?.try_into()?,
133 required_field("inbound_id", self.inbound_id)?.try_into()?,
134 ))
135 }
136}
137
138impl From<indradb::Vertex> for crate::Vertex {
139 fn from(vertex: indradb::Vertex) -> Self {
140 crate::Vertex {
141 id: Some(vertex.id.into()),
142 t: Some(vertex.t.into()),
143 }
144 }
145}
146
147impl TryInto<indradb::Vertex> for crate::Vertex {
148 type Error = ConversionError;
149
150 fn try_into(self) -> Result<indradb::Vertex, Self::Error> {
151 Ok(indradb::Vertex::with_id(
152 required_field("id", self.id)?.try_into()?,
153 required_field("t", self.t)?.try_into()?,
154 ))
155 }
156}
157
158impl From<indradb::Query> for crate::Query {
159 fn from(q: indradb::Query) -> Self {
160 crate::Query {
161 query: Some(match q {
162 indradb::Query::AllVertex => crate::QueryVariant::AllVertex(()),
163 indradb::Query::RangeVertex(q) => crate::QueryVariant::RangeVertex(crate::RangeVertexQuery {
164 limit: q.limit,
165 t: q.t.map(|t| t.into()),
166 start_id: q.start_id.map(|start_id| start_id.into()),
167 }),
168 indradb::Query::SpecificVertex(q) => crate::QueryVariant::SpecificVertex(crate::SpecificVertexQuery {
169 ids: q.ids.into_iter().map(|id| id.into()).collect(),
170 }),
171 indradb::Query::VertexWithPropertyPresence(q) => {
172 crate::QueryVariant::VertexWithPropertyPresence(crate::VertexWithPropertyPresenceQuery {
173 name: Some(q.name.into()),
174 })
175 }
176 indradb::Query::VertexWithPropertyValue(q) => {
177 crate::QueryVariant::VertexWithPropertyValue(crate::VertexWithPropertyValueQuery {
178 name: Some(q.name.into()),
179 value: Some(q.value.into()),
180 })
181 }
182
183 indradb::Query::AllEdge => crate::QueryVariant::AllEdge(()),
184 indradb::Query::SpecificEdge(q) => crate::QueryVariant::SpecificEdge(crate::SpecificEdgeQuery {
185 edges: q.edges.into_iter().map(|id| id.into()).collect(),
186 }),
187 indradb::Query::EdgeWithPropertyPresence(q) => {
188 crate::QueryVariant::EdgeWithPropertyPresence(crate::EdgeWithPropertyPresenceQuery {
189 name: Some(q.name.into()),
190 })
191 }
192 indradb::Query::EdgeWithPropertyValue(q) => {
193 crate::QueryVariant::EdgeWithPropertyValue(crate::EdgeWithPropertyValueQuery {
194 name: Some(q.name.into()),
195 value: Some(q.value.into()),
196 })
197 }
198
199 indradb::Query::Pipe(q) => {
200 let mut proto_q = crate::PipeQuery {
201 inner: Some(Box::new((*q.inner).into())),
202 direction: 0,
203 limit: q.limit,
204 t: q.t.map(|t| t.into()),
205 };
206 proto_q.set_direction(q.direction.into());
207 crate::QueryVariant::Pipe(Box::new(proto_q))
208 }
209 indradb::Query::PipeProperty(q) => {
210 let proto_q = crate::PipePropertyQuery {
211 inner: Some(Box::new((*q.inner).into())),
212 name: q.name.map(|name| name.into()),
213 };
214 crate::QueryVariant::PipeProperty(Box::new(proto_q))
215 }
216 indradb::Query::PipeWithPropertyPresence(q) => {
217 let proto_q = crate::PipeWithPropertyPresenceQuery {
218 inner: Some(Box::new((*q.inner).into())),
219 name: Some(q.name.into()),
220 exists: q.exists,
221 };
222 crate::QueryVariant::PipeWithPropertyPresence(Box::new(proto_q))
223 }
224 indradb::Query::PipeWithPropertyValue(q) => {
225 let proto_q = crate::PipeWithPropertyValueQuery {
226 inner: Some(Box::new((*q.inner).into())),
227 name: Some(q.name.into()),
228 value: Some(q.value.into()),
229 equal: q.equal,
230 };
231 crate::QueryVariant::PipeWithPropertyValue(Box::new(proto_q))
232 }
233
234 indradb::Query::Include(q) => {
235 let proto_q = crate::IncludeQuery {
236 inner: Some(Box::new((*q.inner).into())),
237 };
238 crate::QueryVariant::Include(Box::new(proto_q))
239 }
240 indradb::Query::Count(q) => {
241 let proto_q = crate::CountQuery {
242 inner: Some(Box::new((*q.inner).into())),
243 };
244 crate::QueryVariant::Count(Box::new(proto_q))
245 }
246 }),
247 }
248 }
249}
250
251impl TryInto<indradb::Query> for crate::Query {
252 type Error = ConversionError;
253
254 fn try_into(self) -> Result<indradb::Query, Self::Error> {
255 Ok(match required_field("query", self.query)? {
256 crate::QueryVariant::AllVertex(_q) => indradb::Query::AllVertex,
257 crate::QueryVariant::RangeVertex(q) => indradb::Query::RangeVertex(indradb::RangeVertexQuery {
258 limit: q.limit,
259 t: q.t.map(|t| t.try_into()).transpose()?,
260 start_id: q.start_id.map(|start_id| start_id.try_into()).transpose()?,
261 }),
262 crate::QueryVariant::SpecificVertex(q) => {
263 let ids: Result<Vec<Uuid>, ConversionError> = q.ids.into_iter().map(|id| id.try_into()).collect();
264 indradb::Query::SpecificVertex(indradb::SpecificVertexQuery { ids: ids? })
265 }
266 crate::QueryVariant::VertexWithPropertyPresence(q) => {
267 let name = required_field("name", q.name)?;
268 indradb::Query::VertexWithPropertyPresence(indradb::VertexWithPropertyPresenceQuery {
269 name: name.try_into()?,
270 })
271 }
272 crate::QueryVariant::VertexWithPropertyValue(q) => {
273 let name = required_field("name", q.name)?;
274 let value = required_field("value", q.value)?;
275 indradb::Query::VertexWithPropertyValue(indradb::VertexWithPropertyValueQuery {
276 name: name.try_into()?,
277 value: value.try_into()?,
278 })
279 }
280
281 crate::QueryVariant::AllEdge(_q) => indradb::Query::AllEdge,
282 crate::QueryVariant::SpecificEdge(q) => {
283 let edges: Result<Vec<indradb::Edge>, ConversionError> =
284 q.edges.into_iter().map(|id| id.try_into()).collect();
285 indradb::Query::SpecificEdge(indradb::SpecificEdgeQuery { edges: edges? })
286 }
287 crate::QueryVariant::EdgeWithPropertyPresence(q) => {
288 let name = required_field("name", q.name)?;
289 indradb::Query::EdgeWithPropertyPresence(indradb::EdgeWithPropertyPresenceQuery {
290 name: name.try_into()?,
291 })
292 }
293 crate::QueryVariant::EdgeWithPropertyValue(q) => {
294 let name = required_field("name", q.name)?;
295 let value = required_field("value", q.value)?;
296 indradb::Query::EdgeWithPropertyValue(indradb::EdgeWithPropertyValueQuery {
297 name: name.try_into()?,
298 value: value.try_into()?,
299 })
300 }
301
302 crate::QueryVariant::Pipe(q) => {
303 let direction = q.direction().into();
304 let limit = q.limit;
305 let t = q.t.map(|t| t.try_into()).transpose()?;
306 let inner = required_field("inner", q.inner)?;
307 indradb::Query::Pipe(indradb::PipeQuery {
308 direction,
309 limit,
310 t,
311 inner: Box::new((*inner).try_into()?),
312 })
313 }
314 crate::QueryVariant::PipeProperty(q) => {
315 let inner = required_field("inner", q.inner)?;
316 let name = q.name.map(|n| n.try_into()).transpose()?;
317 indradb::Query::PipeProperty(indradb::PipePropertyQuery {
318 inner: Box::new((*inner).try_into()?),
319 name,
320 })
321 }
322 crate::QueryVariant::PipeWithPropertyPresence(q) => {
323 let inner = required_field("inner", q.inner)?;
324 let name = required_field("name", q.name)?;
325 indradb::Query::PipeWithPropertyPresence(indradb::PipeWithPropertyPresenceQuery {
326 inner: Box::new((*inner).try_into()?),
327 name: name.try_into()?,
328 exists: q.exists,
329 })
330 }
331 crate::QueryVariant::PipeWithPropertyValue(q) => {
332 let inner = required_field("inner", q.inner)?;
333 let name = required_field("name", q.name)?;
334 let value = required_field("value", q.value)?;
335 indradb::Query::PipeWithPropertyValue(indradb::PipeWithPropertyValueQuery {
336 inner: Box::new((*inner).try_into()?),
337 name: name.try_into()?,
338 value: value.try_into()?,
339 equal: q.equal,
340 })
341 }
342
343 crate::QueryVariant::Include(q) => {
344 let inner = required_field("inner", q.inner)?;
345 indradb::Query::Include(indradb::IncludeQuery {
346 inner: Box::new((*inner).try_into()?),
347 })
348 }
349 crate::QueryVariant::Count(q) => {
350 let inner = required_field("inner", q.inner)?;
351 indradb::Query::Count(indradb::CountQuery {
352 inner: Box::new((*inner).try_into()?),
353 })
354 }
355 })
356 }
357}
358
359impl From<indradb::QueryOutputValue> for crate::QueryOutputValue {
360 fn from(output: indradb::QueryOutputValue) -> Self {
361 let variant = match output {
362 indradb::QueryOutputValue::Vertices(vertices) => {
363 crate::QueryOutputValueVariant::Vertices(crate::QueryOutputVertices {
364 vertices: vertices.into_iter().map(|e| e.into()).collect(),
365 })
366 }
367 indradb::QueryOutputValue::Edges(edges) => crate::QueryOutputValueVariant::Edges(crate::QueryOutputEdges {
368 edges: edges.into_iter().map(|e| e.into()).collect(),
369 }),
370 indradb::QueryOutputValue::Count(count) => crate::QueryOutputValueVariant::Count(count),
371 indradb::QueryOutputValue::VertexProperties(vertex_properties) => {
372 crate::QueryOutputValueVariant::VertexProperties(crate::QueryOutputVertexProperties {
373 vertex_properties: vertex_properties.into_iter().map(|vp| vp.into()).collect(),
374 })
375 }
376 indradb::QueryOutputValue::EdgeProperties(edge_properties) => {
377 crate::QueryOutputValueVariant::EdgeProperties(crate::QueryOutputEdgeProperties {
378 edge_properties: edge_properties.into_iter().map(|ep| ep.into()).collect(),
379 })
380 }
381 };
382
383 crate::QueryOutputValue { value: Some(variant) }
384 }
385}
386
387impl TryInto<indradb::QueryOutputValue> for crate::QueryOutputValue {
388 type Error = ConversionError;
389
390 fn try_into(self) -> Result<indradb::QueryOutputValue, Self::Error> {
391 Ok(match required_field("value", self.value)? {
392 crate::QueryOutputValueVariant::Vertices(vertices) => {
393 let vertices: Result<Vec<indradb::Vertex>, ConversionError> =
394 vertices.vertices.into_iter().map(|v| v.try_into()).collect();
395 indradb::QueryOutputValue::Vertices(vertices?)
396 }
397 crate::QueryOutputValueVariant::Edges(edges) => {
398 let edges: Result<Vec<indradb::Edge>, ConversionError> =
399 edges.edges.into_iter().map(|e| e.try_into()).collect();
400 indradb::QueryOutputValue::Edges(edges?)
401 }
402 crate::QueryOutputValueVariant::Count(count) => indradb::QueryOutputValue::Count(count),
403 crate::QueryOutputValueVariant::VertexProperties(vertex_properties) => {
404 let vertex_properties: Result<Vec<indradb::VertexProperties>, ConversionError> = vertex_properties
405 .vertex_properties
406 .into_iter()
407 .map(|vp| vp.try_into())
408 .collect();
409 indradb::QueryOutputValue::VertexProperties(vertex_properties?)
410 }
411 crate::QueryOutputValueVariant::EdgeProperties(edge_properties) => {
412 let edge_properties: Result<Vec<indradb::EdgeProperties>, ConversionError> = edge_properties
413 .edge_properties
414 .into_iter()
415 .map(|ep| ep.try_into())
416 .collect();
417 indradb::QueryOutputValue::EdgeProperties(edge_properties?)
418 }
419 })
420 }
421}
422
423impl From<indradb::EdgeDirection> for crate::EdgeDirection {
424 fn from(direction: indradb::EdgeDirection) -> Self {
425 match direction {
426 indradb::EdgeDirection::Outbound => crate::EdgeDirection::Outbound,
427 indradb::EdgeDirection::Inbound => crate::EdgeDirection::Inbound,
428 }
429 }
430}
431
432impl From<crate::EdgeDirection> for indradb::EdgeDirection {
433 fn from(direction: crate::EdgeDirection) -> Self {
434 match direction {
435 crate::EdgeDirection::Outbound => indradb::EdgeDirection::Outbound,
436 crate::EdgeDirection::Inbound => indradb::EdgeDirection::Inbound,
437 }
438 }
439}
440
441impl From<indradb::NamedProperty> for crate::NamedProperty {
442 fn from(prop: indradb::NamedProperty) -> Self {
443 crate::NamedProperty {
444 name: Some(prop.name.into()),
445 value: Some(prop.value.into()),
446 }
447 }
448}
449
450impl TryInto<indradb::NamedProperty> for crate::NamedProperty {
451 type Error = ConversionError;
452
453 fn try_into(self) -> Result<indradb::NamedProperty, Self::Error> {
454 Ok(indradb::NamedProperty::new(
455 required_field("name", self.name)?.try_into()?,
456 required_field("value", self.value)?.try_into()?,
457 ))
458 }
459}
460
461impl From<indradb::VertexProperty> for crate::VertexProperty {
462 fn from(prop: indradb::VertexProperty) -> Self {
463 crate::VertexProperty {
464 id: Some(prop.id.into()),
465 value: Some(prop.value.into()),
466 }
467 }
468}
469
470impl TryInto<indradb::VertexProperty> for crate::VertexProperty {
471 type Error = ConversionError;
472
473 fn try_into(self) -> Result<indradb::VertexProperty, Self::Error> {
474 Ok(indradb::VertexProperty::new(
475 required_field("id", self.id)?.try_into()?,
476 required_field("value", self.value)?.try_into()?,
477 ))
478 }
479}
480
481impl From<indradb::VertexProperties> for crate::VertexProperties {
482 fn from(props: indradb::VertexProperties) -> Self {
483 crate::VertexProperties {
484 vertex: Some(props.vertex.into()),
485 props: props.props.into_iter().map(|prop| prop.into()).collect(),
486 }
487 }
488}
489
490impl TryInto<indradb::VertexProperties> for crate::VertexProperties {
491 type Error = ConversionError;
492
493 fn try_into(self) -> Result<indradb::VertexProperties, Self::Error> {
494 let props: Result<Vec<indradb::NamedProperty>, ConversionError> =
495 self.props.into_iter().map(|prop| prop.try_into()).collect();
496 Ok(indradb::VertexProperties::new(
497 required_field("vertex", self.vertex)?.try_into()?,
498 props?,
499 ))
500 }
501}
502
503impl From<indradb::EdgeProperty> for crate::EdgeProperty {
504 fn from(prop: indradb::EdgeProperty) -> Self {
505 crate::EdgeProperty {
506 edge: Some(prop.edge.into()),
507 value: Some(prop.value.into()),
508 }
509 }
510}
511
512impl TryInto<indradb::EdgeProperty> for crate::EdgeProperty {
513 type Error = ConversionError;
514
515 fn try_into(self) -> Result<indradb::EdgeProperty, Self::Error> {
516 Ok(indradb::EdgeProperty::new(
517 required_field("edge", self.edge)?.try_into()?,
518 required_field("value", self.value)?.try_into()?,
519 ))
520 }
521}
522
523impl From<indradb::EdgeProperties> for crate::EdgeProperties {
524 fn from(props: indradb::EdgeProperties) -> Self {
525 crate::EdgeProperties {
526 edge: Some(props.edge.into()),
527 props: props.props.into_iter().map(|prop| prop.into()).collect(),
528 }
529 }
530}
531
532impl TryInto<indradb::EdgeProperties> for crate::EdgeProperties {
533 type Error = ConversionError;
534
535 fn try_into(self) -> Result<indradb::EdgeProperties, Self::Error> {
536 let props: Result<Vec<indradb::NamedProperty>, ConversionError> =
537 self.props.into_iter().map(|prop| prop.try_into()).collect();
538 Ok(indradb::EdgeProperties::new(
539 required_field("edge", self.edge)?.try_into()?,
540 props?,
541 ))
542 }
543}
544
545impl From<indradb::BulkInsertItem> for crate::BulkInsertItem {
546 fn from(item: indradb::BulkInsertItem) -> Self {
547 crate::BulkInsertItem {
548 item: Some(match item {
549 indradb::BulkInsertItem::Vertex(vertex) => crate::BulkInsertItemVariant::Vertex(vertex.into()),
550 indradb::BulkInsertItem::Edge(edge) => crate::BulkInsertItemVariant::Edge(edge.into()),
551 indradb::BulkInsertItem::VertexProperty(id, name, value) => {
552 crate::BulkInsertItemVariant::VertexProperty(crate::VertexPropertyBulkInsertItem {
553 id: Some(id.into()),
554 name: Some(name.into()),
555 value: Some(value.into()),
556 })
557 }
558 indradb::BulkInsertItem::EdgeProperty(edge, name, value) => {
559 crate::BulkInsertItemVariant::EdgeProperty(crate::EdgePropertyBulkInsertItem {
560 edge: Some(edge.into()),
561 name: Some(name.into()),
562 value: Some(value.into()),
563 })
564 }
565 }),
566 }
567 }
568}
569
570impl TryInto<indradb::BulkInsertItem> for crate::BulkInsertItem {
571 type Error = ConversionError;
572
573 fn try_into(self) -> Result<indradb::BulkInsertItem, Self::Error> {
574 Ok(match required_field("item", self.item)? {
575 crate::BulkInsertItemVariant::Vertex(vertex) => indradb::BulkInsertItem::Vertex(vertex.try_into()?),
576 crate::BulkInsertItemVariant::Edge(edge) => indradb::BulkInsertItem::Edge(edge.try_into()?),
577 crate::BulkInsertItemVariant::VertexProperty(item) => indradb::BulkInsertItem::VertexProperty(
578 required_field("id", item.id)?.try_into()?,
579 required_field("name", item.name)?.try_into()?,
580 required_field("value", item.value)?.try_into()?,
581 ),
582 crate::BulkInsertItemVariant::EdgeProperty(item) => indradb::BulkInsertItem::EdgeProperty(
583 required_field("edge", item.edge)?.try_into()?,
584 required_field("name", item.name)?.try_into()?,
585 required_field("value", item.value)?.try_into()?,
586 ),
587 })
588 }
589}
590
591impl TryInto<indradb::Identifier> for crate::IndexPropertyRequest {
592 type Error = ConversionError;
593
594 fn try_into(self) -> Result<indradb::Identifier, Self::Error> {
595 let name = required_field("name", self.name)?.try_into()?;
596 Ok(name)
597 }
598}
599
600impl TryInto<(indradb::Query, indradb::Identifier, indradb::Json)> for crate::SetPropertiesRequest {
601 type Error = ConversionError;
602
603 fn try_into(self) -> Result<(indradb::Query, indradb::Identifier, indradb::Json), Self::Error> {
604 let q = required_field("q", self.q)?.try_into()?;
605 let name = required_field("name", self.name)?.try_into()?;
606 let value = required_field("value", self.value)?.try_into()?;
607 Ok((q, name, value))
608 }
609}
610
611impl From<(indradb::Query, indradb::Identifier, indradb::Json)> for crate::SetPropertiesRequest {
612 fn from(value: (indradb::Query, indradb::Identifier, indradb::Json)) -> Self {
613 crate::SetPropertiesRequest {
614 q: Some(value.0.into()),
615 name: Some(value.1.into()),
616 value: Some(value.2.into()),
617 }
618 }
619}