Skip to main content

surrealdb_expr/val/value/
generate.rs

1use anyhow::Result;
2use surrealdb_types::ToSql;
3
4use crate::expr::Error;
5use crate::val::{RecordId, RecordIdKey, TableName, Value};
6
7impl Value {
8	pub fn generate(self, tb: TableName, retable: bool) -> Result<RecordId> {
9		match self {
10			// There is a floating point number for the id field. Only accept
11			// floats that round-trip exactly to an i64 (finite, whole, in
12			// range). Lossy conversions are rejected — see
13			// `Number::as_int_lossless`.
14			Value::Number(id) if id.is_float() => {
15				let key = id.as_int_lossless().map(RecordIdKey::Number).ok_or_else(|| {
16					anyhow::Error::new(Error::IdInvalid {
17						value: Value::Number(id).to_sql(),
18					})
19				})?;
20				Ok(RecordId {
21					table: tb,
22					key,
23				})
24			}
25			// There is an integer number for the id field
26			Value::Number(id) if id.is_int() => Ok(RecordId {
27				table: tb,
28				key: RecordIdKey::Number(id.as_int()),
29			}),
30			// There is a string for the id field
31			Value::String(id) if !id.is_empty() => Ok(RecordId {
32				table: tb,
33				key: id.into(),
34			}),
35			// There is an object for the id field
36			Value::Object(id) => Ok(RecordId {
37				table: tb,
38				key: id.into(),
39			}),
40			// There is an array for the id field
41			Value::Array(id) => Ok(RecordId {
42				table: tb,
43				key: id.into(),
44			}),
45			// There is a UUID for the id field
46			Value::Uuid(id) => Ok(RecordId {
47				table: tb,
48				key: id.into(),
49			}),
50			// There is no record id field
51			Value::None => Ok(RecordId {
52				table: tb,
53				key: RecordIdKey::rand(),
54			}),
55			// There is a record id defined
56			Value::RecordId(id) => {
57				if retable {
58					// Let's re-table this record id
59					Ok(RecordId {
60						table: tb,
61						key: id.key,
62					})
63				} else {
64					// Let's use the specified record id
65					if tb == id.table {
66						// The record is from the same table
67						Ok(id)
68					} else {
69						// The record id is from another table
70						Ok(RecordId {
71							table: tb,
72							key: id.key,
73						})
74					}
75				}
76			}
77			// Any other value is wrong
78			id => Err(anyhow::Error::new(Error::IdInvalid {
79				value: id.to_sql(),
80			})),
81		}
82	}
83}