nushell/crates/nu-parser/src
mike 77ca73f414
allow records to have type annotations (#8914)
# Description
follow up to #8529
cleaned up version of #8892 

- the original syntax is okay
```nu
def okay [rec: record] {}
```
- you can now add type annotations for fields if you know
  them before hand
```nu
def okay [rec: record<name: string>] {}
```

- you can specify multiple fields
```nu
def okay [person: record<name: string age: int>] {}

# an optional comma is allowed
def okay [person: record<name: string, age: int>] {}
```

- if annotations are specified, any use of the command will be type
  checked against the specified type
```nu
def unwrap [result: record<ok: bool, value: any>] {}

unwrap {ok: 2, value: "value"}

# errors with

Error: nu::parser::type_mismatch

  × Type mismatch.
   ╭─[entry #4:1:1]
 1 │ unwrap {ok: 2, value: "value"}
   ·         ───────┬─────
   ·                    ╰── expected record<ok: bool, value: any>, found record<ok: int, value: string>
   ╰────
```
> here the error is in the `ok` field, since `any` is coerced into any
type
> as a result `unwrap {ok: true, value: "value"}` is okay

- the key must be a string, either quoted or unquoted
```nu
def err [rec: record<{}: list>] {}

# errors with
Error:
  × `record` type annotations key not string
   ╭─[entry #7:1:1]
 1 │ def unwrap [result: record<{}: bool, value: any>] {}
   ·                            ─┬
   ·                             ╰── must be a string
   ╰────
```

- a key doesn't have to have a type in which case it is assumed to be
`any`
```nu
def okay [person: record<name age>] {}

def okay [person: record<name: string age>] {}
```

- however, if you put a colon, you have to specify a type
```nu
def err [person: record<name: >] {}

# errors with
Error: nu::parser::parse_mismatch

  × Parse mismatch during operation.
   ╭─[entry #12:1:1]
 1 │ def unwrap [res: record<name: >] { $res }
   ·                             ┬
   ·                             ╰── expected type after colon
   ╰────
```

# User-Facing Changes
**[BREAKING CHANGES]**
- this change adds a field to `SyntaxShape::Record` so any plugins that
used it will have to update and include the field. though if you are
unsure of the type the record expects, `SyntaxShape::Record(vec![])`
will suffice
2023-04-26 08:16:55 -05:00
..
deparse.rs Use variable names directly in the format strings (#7906) 2023-01-29 19:37:54 -06:00
eval.rs allow register to accept a const argument (#8758) 2023-04-08 15:04:57 -05:00
flatten.rs Relax the closure syntax, highlight differently (#8846) 2023-04-12 05:21:52 +12:00
known_external.rs Document and critically review ShellError variants - Ep. 3 (#8340) 2023-03-06 18:33:09 +01:00
lex.rs Fix strange error on unbalanced curly braces (#8906) 2023-04-17 21:51:10 +12:00
lib.rs Refactor to support multiple parse errors (#8765) 2023-04-07 12:35:45 +12:00
lite_parser.rs Refactor to support multiple parse errors (#8765) 2023-04-07 12:35:45 +12:00
parse_keywords.rs Reuse the cached parse results of parsed files (#8949) 2023-04-22 07:00:33 +12:00
parse_patterns.rs Remove old alias implementation (#8797) 2023-04-07 21:09:38 +03:00
parser.rs allow records to have type annotations (#8914) 2023-04-26 08:16:55 -05:00
type_check.rs allow records to have type annotations (#8914) 2023-04-26 08:16:55 -05:00