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}