Search code examples
scalaplayframeworktypesafe-config

*Ordered* objects in Play (Scala) typesafe config


How do I access the ordered list of customers in the following .conf in Play 2.6.x (Scala):

customers {
  "cust1" {
    env1 {
      att1: "str1"
      att2: "str2"
    }
    env2 {
      att1: "str3"
      att2: "str5"
    }
    env3 {
      att1: "str2"
      att2: "str6"
    }
    env4 {
      att1: "str1"
      att2: "str2"
    }
  }
  "cust2" {
    env1 {
      att1: "faldfjalfj"
      att2: "reqwrewrqrq"
    }
    env2 {
      att1: "falalfj"
      att2: "reqwrrq"
    }
  }
  "cust3" {
    env3 {
      att1: "xvcbzxbv"
      att2: "hello"
    }
  }
}

List("cust1", "cust2", "cust3"), in this example.


Solution

  • The following example should work:

    val config : Configuration = ???
    config.getObject("customers").entrySet().asScala.map(_.getKey).toList
    

    Edit

    If customers are in lexicographical order than you can order call .sorted

    If changing your config doesn't affect your already implemented logic than you can restructure your config like this:

    customers : [
      {
        name : "cust1"
        env1 {
          att1: "str1"
          att2: "str2"
        }
        env2 {
          att1: "str3"
          att2: "str5"
        }
        env3 {
          att1: "str2"
          att2: "str6"
        }
        env4 {
          att1: "str1"
          att2: "str2"
        }
      }
       {
        name : "cust2"
        env1 {
          att1: "faldfjalfj"
          att2: "reqwrewrqrq"
        }
        env2 {
          att1: "falalfj"
          att2: "reqwrrq"
        }
      }
      {
        name: "cust3"
        env3 {
          att1: "xvcbzxbv"
          att2: "hello"
        }
      }
      {
        name : "bob"
        env1 {
          att1: "str1"
          att2: "str2"
        }
        env2 {
          att1: "str3"
          att2: "str5"
        }
        env3 {
          att1: "str2"
          att2: "str6"
        }
        env4 {
          att1: "str1"
          att2: "str2"
        }
      }
      {
        name : "john"
        env1 {
          att1: "faldfjalfj"
          att2: "reqwrewrqrq"
        }
        env2 {
          att1: "falalfj"
          att2: "reqwrrq"
        }
      }
      {
        name: "jack"
        env3 {
          att1: "xvcbzxbv"
          att2: "hello"
        }
      }
    ]
    

    and with pureconfig you can do the following:

    import pureconfig.loadConfigOrThrow
    
    final case class Named(name: String)
    
    loadConfigOrThrow[List[Named]]("customers").map(_.name)