I'm thinking about using tuple for i18n names e.g.:
type Category {
required property i18nName: tuple<pl: str, en: str>;
}
It's possible to select from tuple by dot property:
> select (pl := "bober", en:= "beaver")).pl;
{"bober"}
But let's say I want to make the language key dynamic:
> with lng := <str>$lng select (pl := "bober", en:= "beaver")[lng];
gel error: QueryError: index indirection cannot be applied to collection 'tuple<pl: std::str, en: std::str>'
Can this be achieved with the tuple?
I came up with a way by casting the tuple to JSON, and then using json_get
:
with lng := $lng
select <str>json_get(<json>(pl := "bober", en:= "beaver"), lng))));
Also, I was able to constrain the keys by going through a function, to make sure only valid calls are made:
scalar type Lang extending str {
constraint one_of("pl", 'en');
}
function get_tuple_lang(tpl: tuple<pl: str, en: str>, lng: Lang) -> str
using (assert_exists(assert_single(<str>json_get(<json>tpl, lng))));
This works:
project:main> with t := (pl:="bober", en:="beaver") select get_tuple_lang(t, "pl");
{'bober'}
project:main> with t := (pl:="bober", en:="beaver") select get_tuple_lang(t, "en");
{'beaver'}
project:main> with t := (pl:="bober", en:="beaver") select get_tuple_lang(t, "cz");
gel error: ConstraintViolationError: Lang must be one of: ['pl', 'en'].
Detail: violated constraint 'std::one_of' on scalar type 'default::Lang'