valence_core/
connection.rs1use std::fmt;
4
5use crate::error::{Error, Result};
6use crate::RecordId;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Cardinality {
10 HasOne,
11 HasMany,
12 ManyToMany,
13}
14
15impl fmt::Display for Cardinality {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 match self {
18 Cardinality::HasOne => write!(f, "HasOne"),
19 Cardinality::HasMany => write!(f, "HasMany"),
20 Cardinality::ManyToMany => write!(f, "ManyToMany"),
21 }
22 }
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum OnDelete {
27 Cascade,
28 SetNull,
29 Restrict,
30}
31
32impl fmt::Display for OnDelete {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 OnDelete::Cascade => write!(f, "Cascade"),
36 OnDelete::SetNull => write!(f, "SetNull"),
37 OnDelete::Restrict => write!(f, "Restrict"),
38 }
39 }
40}
41
42pub fn id_from_model<T>(model: &T) -> Result<String>
43where
44 T: IdHolder,
45{
46 let r = model
47 .record_id()
48 .ok_or_else(|| Error::Validation("Model has no id (new/unsaved record)".into()))?;
49 extract_id_from_record(r)
50}
51
52pub trait IdHolder {
53 fn record_id(&self) -> Option<&RecordId>;
54}
55
56pub fn extract_id_from_record(r: &RecordId) -> Result<String> {
57 Ok(r.id().to_string())
58}
59
60pub fn extract_id_from_record_display(s: &str) -> Result<String> {
61 let id = s.split_once(':').map_or(s, |(_, id_part)| id_part).trim();
62 let id = id
63 .trim_start_matches(['⟨', '‹', '«'])
64 .trim_end_matches(['⟩', '›', '»']);
65 if id.is_empty() {
66 return Err(Error::Validation(format!(
67 "Invalid record id string: could not extract ID from {s:?}"
68 )));
69 }
70 Ok(id.to_string())
71}
72
73pub fn extract_id_from_select_value(v: &serde_json::Value) -> Result<String> {
74 if let Ok(rid) = serde_json::from_value::<RecordId>(v.clone()) {
75 return extract_id_from_record(&rid);
76 }
77 match v {
78 serde_json::Value::String(s) => extract_id_from_record_display(s),
79 serde_json::Value::Number(n) => Ok(n.to_string()),
80 serde_json::Value::Bool(b) => Ok(b.to_string()),
81 _ => Err(Error::Internal(format!(
82 "unexpected id value in query row: {v}"
83 ))),
84 }
85}