dbml_rs/ast/
refs.rs

1use alloc::string::{
2  String,
3  ToString,
4};
5use alloc::vec::Vec;
6use core::str::FromStr;
7
8use super::*;
9
10#[derive(Debug, Clone, Default)]
11pub struct RefInline {
12  /// The range of the span in the source text.
13  pub span_range: SpanRange,
14  pub rel: Relation,
15  pub rhs: RefIdent,
16}
17
18#[derive(Debug, Clone, Default)]
19pub struct RefBlock {
20  /// The range of the span in the source text.
21  pub span_range: SpanRange,
22  pub name: Option<Ident>,
23  pub rel: Relation,
24  pub lhs: RefIdent,
25  pub rhs: RefIdent,
26  pub settings: Option<RefSettings>,
27}
28
29#[derive(Debug, PartialEq, Eq, Clone, Default)]
30pub enum Relation {
31  #[default]
32  Undef,
33  /// Represents '-' one-to-one. E.g: `users.id` - `user_infos.user_id`.
34  One2One,
35  /// Represents '<' one-to-many. E.g: `users.id` < `posts.user_id`.
36  One2Many,
37  /// Represents '>' many-to-one. E.g: `posts.user_id` > `users.id`.
38  Many2One,
39  /// Represents '<>' many-to-many. E.g: `authors.id` <> `books.id`.
40  Many2Many,
41}
42
43impl FromStr for Relation {
44  type Err = String;
45
46  fn from_str(s: &str) -> Result<Self, Self::Err> {
47    match s {
48      "<" => Ok(Self::One2Many),
49      ">" => Ok(Self::Many2One),
50      "-" => Ok(Self::One2One),
51      "<>" => Ok(Self::Many2Many),
52      _ => Err(format!("invalid relation symbol '{}'", s)),
53    }
54  }
55}
56
57#[derive(Debug, Clone, Default)]
58pub struct RefIdent {
59  /// The range of the span in the source text.
60  pub span_range: SpanRange,
61  pub schema: Option<Ident>,
62  pub table: Ident,
63  pub compositions: Vec<Ident>,
64}
65
66#[derive(Debug, Clone)]
67pub enum ReferentialAction {
68  NoAction,
69  Cascade,
70  Restrict,
71  SetNull,
72  SetDefault,
73}
74
75impl FromStr for ReferentialAction {
76  type Err = String;
77
78  fn from_str(s: &str) -> Result<Self, Self::Err> {
79    match s {
80      "no action" => Ok(Self::NoAction),
81      "cascade" => Ok(Self::Cascade),
82      "restrict" => Ok(Self::Restrict),
83      "set null" => Ok(Self::SetNull),
84      "set default" => Ok(Self::SetDefault),
85      _ => Err("invalid referential action".to_string()),
86    }
87  }
88}
89
90impl ToString for ReferentialAction {
91  fn to_string(&self) -> String {
92    let s = match self {
93      Self::NoAction => "no action",
94      Self::Cascade => "cascade",
95      Self::Restrict => "restrict",
96      Self::SetNull => "set null",
97      Self::SetDefault => "set default",
98    };
99
100    s.to_string()
101  }
102}
103
104#[derive(Debug, Clone, Default)]
105pub struct RefSettings {
106  /// The range of the span in the source text.
107  pub span_range: SpanRange,
108  /// A vector of key and optional value pairs representing attributes of the ref.
109  pub attributes: Vec<Attribute>,
110  pub on_delete: Option<ReferentialAction>,
111  pub on_update: Option<ReferentialAction>,
112}