| 1490 | |
| 1491 | /** @internal */ |
| 1492 | export const getLiterals = ( |
| 1493 | ast: AST.AST, |
| 1494 | isDecoding: boolean |
| 1495 | ): ReadonlyArray<[PropertyKey, AST.Literal]> => { |
| 1496 | switch (ast._tag) { |
| 1497 | case "Declaration": { |
| 1498 | const annotation = AST.getSurrogateAnnotation(ast) |
| 1499 | if (Option.isSome(annotation)) { |
| 1500 | return getLiterals(annotation.value, isDecoding) |
| 1501 | } |
| 1502 | break |
| 1503 | } |
| 1504 | case "TypeLiteral": { |
| 1505 | const out: Array<[PropertyKey, AST.Literal]> = [] |
| 1506 | for (let i = 0; i < ast.propertySignatures.length; i++) { |
| 1507 | const propertySignature = ast.propertySignatures[i] |
| 1508 | const type = isDecoding ? AST.encodedAST(propertySignature.type) : AST.typeAST(propertySignature.type) |
| 1509 | if (AST.isLiteral(type) && !propertySignature.isOptional) { |
| 1510 | out.push([propertySignature.name, type]) |
| 1511 | } |
| 1512 | } |
| 1513 | return out |
| 1514 | } |
| 1515 | case "TupleType": { |
| 1516 | const out: Array<[PropertyKey, AST.Literal]> = [] |
| 1517 | for (let i = 0; i < ast.elements.length; i++) { |
| 1518 | const element = ast.elements[i] |
| 1519 | const type = isDecoding ? AST.encodedAST(element.type) : AST.typeAST(element.type) |
| 1520 | if (AST.isLiteral(type) && !element.isOptional) { |
| 1521 | out.push([i, type]) |
| 1522 | } |
| 1523 | } |
| 1524 | return out |
| 1525 | } |
| 1526 | case "Refinement": |
| 1527 | return getLiterals(ast.from, isDecoding) |
| 1528 | case "Suspend": |
| 1529 | return getLiterals(ast.f(), isDecoding) |
| 1530 | case "Transformation": |
| 1531 | return getLiterals(isDecoding ? ast.from : ast.to, isDecoding) |
| 1532 | } |
| 1533 | return [] |
| 1534 | } |
| 1535 | |
| 1536 | /** |
| 1537 | * The purpose of the algorithm is to narrow down the pool of possible |