1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::{borrow::Cow, fmt};

use crate::value::{Array, Constant, Function, Text, Value};

use super::attributes::FieldAttribute;

/// A field default value.
#[derive(Debug)]
pub struct DefaultValue<'a>(FieldAttribute<'a>);

impl<'a> DefaultValue<'a> {
    /// A function default value.
    ///
    /// ```ignore
    /// model Foo {
    ///   field String @default(uuid())
    ///                         ^^^^ this
    /// }
    /// ```
    pub fn function(mut function: Function<'a>) -> Self {
        // Our specialty in default values, empty function params lead to
        // parentheses getting rendered unlike elsewhere.
        function.render_empty_parentheses();

        let mut inner = Function::new("default");
        inner.push_param(Value::from(function));

        Self::new(inner)
    }

    /// A textual default value.
    ///
    /// ```ignore
    /// model Foo {
    ///   field String @default("meow")
    ///                          ^^^^ this
    /// }
    /// ```
    pub fn text(value: impl Into<Cow<'a, str>>) -> Self {
        let mut inner = Function::new("default");
        inner.push_param(Value::from(Text::new(value)));

        Self::new(inner)
    }

    /// A byte array default value, base64-encoded.
    ///
    /// ```ignore
    /// model Foo {
    ///   field String @default("deadbeef")
    ///                          ^^^^^^^^ this
    /// }
    /// ```
    pub fn bytes(value: impl Into<Cow<'a, [u8]>>) -> Self {
        let mut inner = Function::new("default");
        inner.push_param(Value::from(value.into().into_owned()));

        Self::new(inner)
    }

    /// A constant default value.
    ///
    /// ```ignore
    /// model Foo {
    ///   field String @default(666420)
    ///                         ^^^^^^ this
    /// }
    /// ```
    pub fn constant<T>(value: T) -> Self
    where
        T: fmt::Display + 'a,
    {
        let mut inner = Function::new("default");
        inner.push_param(Value::from(Constant::new_no_validate(value)));

        Self::new(inner)
    }

    /// An array default value.
    ///
    /// ```ignore
    /// model Foo {
    ///   field String @default([1,2,3])
    ///                          ^^^^^ this
    /// }
    /// ```
    pub fn array<T>(values: Vec<T>) -> Self
    where
        T: fmt::Display + 'a,
    {
        let mut inner = Function::new("default");
        let constant = Box::new(Array::from(values));

        inner.push_param(Value::from(Constant::new_no_validate(constant)));

        Self::new(inner)
    }

    /// Sets the default map argument.
    ///
    /// ```ignore
    /// model Foo {
    ///   field String @default("foo", map: "IDDQDIDKFA")
    ///                                      ^^^^^^^^^^ this
    /// }
    /// ```
    pub fn map(&mut self, mapped_name: impl Into<Cow<'a, str>>) {
        self.0.push_param(("map", Text::new(mapped_name)));
    }

    fn new(inner: Function<'a>) -> Self {
        Self(FieldAttribute::new(inner))
    }
}

impl<'a> fmt::Display for DefaultValue<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.fmt(f)
    }
}