如何在Dhall中表示以下JSON?

问题描述 投票:0回答:1

我正在使用以下JSON表示我们的基础结构。这是一个大大简化的版本。

{
  "us-east-1": {
    "qa": {
      "etcd": {}
    }
  },
  "eu-central-1": {
    "dev": {
      "etcd": {}
    }

  },
  "eu-west-1": {
    "prod": {
      "etcd": {}
    }
  }
}

这可以映射到文件夹,并且很容易从代码中处理。

#!/usr/bin/env python
import json
import os, sys

with open('infrastructure.json', 'r') as read_file: infra = json.load(read_file)

regions = infra.keys()
for region in regions:
    stages = infra[region].keys()
    for stage in stages:
        apps = infra[region][stage].keys()
        for app in apps:
            os.makedirs(os.path.join('infra', region, stage, app), 0o750, exist_ok=True)
            print('region: {}, stage: {}, app: {}'.format(region, stage, app))

但是,我想使用Dhall生成此文件以将可能的键限制为列表。

Dhall为此提供支持:

let AwsRegions : Type = < us-east-1 | eu-central-1 | eu-west-1 >
let Stages : Type = < dev | qa | prod >
let Applications : Type = < etcd | postgresql | hadoop >

唯一的问题是我找不到将记录键作为空类型的支持,只能将值限制为那些。

这使我具有以下方式:

let infrastructure : 
List {  region: AwsRegions, stage: Stages, 
        applications: List Applications } =
[ {     region = AwsRegions.us-east-1, 
        stage =  Stages.dev,
        applications = [ 
            Applications.hadoop, 
            Applications.etcd ] },
    {   region = AwsRegions.eu-west-1, 
        stage =  Stages.dev,
        applications = [ 
            Applications.hadoop, 
            Applications.etcd ] },
    {   region = AwsRegions.eu-central-1, 
        stage =  Stages.dev,
        applications = [ 
            Applications.hadoop, 
            Applications.etcd ] },
    {   region = AwsRegions.eu-west-1, 
        stage =  Stages.qa,
        applications = [ 
            Applications.hadoop, 
            Applications.etcd ] },
    {   region = AwsRegions.eu-west-1, 
        stage =  Stages.prod,
        applications = [ 
            Applications.hadoop, 
            Applications.etcd ] } ]
in infrastructure

生成的JSON从代码中很难处理,我无法像其他表示形式那样轻易地引用我们的基础设施的子集。

是否可以通过Dhall拥有像枚举(空类型的并集)之类的键?

json dhall
1个回答
1
投票

这是生成嵌套的JSON记录的惯用方法,其记录的键限于枚举:

let keyValue =
        λ(k : Type)
      → λ(v : Type)
      → λ(mapKey : k)
      → λ(mapValue : v)
      → { mapKey = mapKey, mapValue = mapValue }

let Prelude = https://prelude.dhall-lang.org/v11.1.0/package.dhall

let Application = < etcd | postgresql | hadoop >

let Applications = Prelude.Map.Type Application {}

let application = λ(application : Application) → keyValue Application {} application {=}

let Stage = < dev | qa | prod >

let Stages = Prelude.Map.Type Stage Applications

let stage = keyValue Stage Applications

let AwsRegion = < us-east-1 | eu-central-1 | eu-west-1 >

let AwsRegions = Prelude.Map.Type AwsRegion Stages

let awsRegion = keyValue AwsRegion Stages

in  [ awsRegion AwsRegion.us-east-1
        [ stage Stage.dev
             [ application Application.hadoop
             , application Application.etcd
             ]
        ]
    , awsRegion AwsRegion.eu-west-1
        [ stage Stage.dev
             [ application Application.hadoop
             , application Application.etcd
             ]
        , stage Stage.qa
             [ application Application.hadoop
             , application Application.etcd
             ]
        , stage Stage.prod
             [ application Application.hadoop
             , application Application.etcd
             ]
        ]
    , awsRegion AwsRegion.eu-central-1
        [ stage Stage.dev
            [ application Application.hadoop
            , application Application.etcd
            ]
        ]
    ]

...呈现为以下JSON:

$ dhall-to-json/dhall-to-json --file /tmp/test/example.dhall 
{
  "eu-central-1": {
    "dev": {
      "etcd": {},
      "hadoop": {}
    }
  },
  "eu-west-1": {
    "dev": {
      "etcd": {},
      "hadoop": {}
    },
    "prod": {
      "etcd": {},
      "hadoop": {}
    },
    "qa": {
      "etcd": {},
      "hadoop": {}
    }
  },
  "us-east-1": {
    "dev": {
      "etcd": {},
      "hadoop": {}
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.