toasty_core/schema/app/fk.rs
1use super::{Field, FieldId, Schema};
2
3/// A foreign key linking one model's fields to another model's primary key.
4///
5/// A `ForeignKey` is composed of one or more [`ForeignKeyField`] pairs, each
6/// mapping a source field (on the owning model) to a target field (on the
7/// referenced model). For single-column primary keys the `fields` vec has one
8/// entry; composite keys have multiple.
9///
10/// # Examples
11///
12/// ```
13/// use toasty_core::schema::app::{ForeignKey, ForeignKeyField, FieldId, ModelId};
14///
15/// let fk = ForeignKey {
16/// fields: vec![ForeignKeyField {
17/// source: ModelId(0).field(1),
18/// target: ModelId(1).field(0),
19/// }],
20/// };
21/// assert_eq!(fk.fields.len(), 1);
22/// ```
23#[derive(Debug, Clone)]
24pub struct ForeignKey {
25 /// The field pairs that make up this foreign key.
26 pub fields: Vec<ForeignKeyField>,
27}
28
29/// One column-pair within a [`ForeignKey`].
30///
31/// Maps a single field on the source (owning) model to the corresponding
32/// field on the target (referenced) model.
33///
34/// # Examples
35///
36/// ```
37/// use toasty_core::schema::app::{ForeignKeyField, ModelId};
38///
39/// let fkf = ForeignKeyField {
40/// source: ModelId(0).field(2),
41/// target: ModelId(1).field(0),
42/// };
43/// ```
44#[derive(Debug, Clone)]
45pub struct ForeignKeyField {
46 /// The field on the source model that stores the foreign key value.
47 pub source: FieldId,
48
49 /// The field on the target model that this foreign key references.
50 pub target: FieldId,
51}
52
53impl ForeignKey {
54 pub(crate) fn is_placeholder(&self) -> bool {
55 self.fields.is_empty()
56 }
57}
58
59impl ForeignKeyField {
60 /// Resolves the source [`Field`] from the given schema.
61 pub fn source<'a>(&self, schema: &'a Schema) -> &'a Field {
62 schema.field(self.source)
63 }
64
65 /// Resolves the target [`Field`] from the given schema.
66 pub fn target<'a>(&self, schema: &'a Schema) -> &'a Field {
67 schema.field(self.target)
68 }
69}