Как преобразовать кортежи DAML, полученные через API DA Ledger, в пары Java? - PullRequest
0 голосов
/ 12 декабря 2018

Я написал модель DAML, которая генерирует список кортежей, например, [(Int, Text)].Я получаю эти данные через API DA Ledger - как мне преобразовать их в List<Pair<Long, String>> в Java?

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Предполагая, что у вас есть следующий шаблон daml:

template ListOfTuples
  with
    party : Party
    listOfTuples : [(Int, Text)]
  where
    signatory party

, который был преобразован в com.daml.ledger.javaapi.data.Record с Java API, вы можете преобразовать его в List<Pair<Long, String>>, обработав кортежи всписок также как Record s:

import java.util.List;
import javafx.util.Pair;
import java.util.stream.Collectors;
import com.daml.ledger.javaapi.data.Record;

public void parseListOfTuples(Record record) {

  List<Pair<Long, String>> listOfTuples =
     record.getFields().get(1).getValue().asList().get().getValues().stream()
             .map(t -> {
                 List<Record.Field> tuple = t.asRecord().get().getFields();
                 return new Pair<>(
                         tuple.get(0).getValue().asInt64().get().getValue(),
                         tuple.get(1).getValue().asText().get().getValue());
             })
             .collect(Collectors.toList());
}
0 голосов
/ 13 декабря 2018

Java зависит от того, работаете ли вы с необработанными скомпилированными типами Protobuf или с обернутыми типами, предоставляемыми привязками языка Java.

Объекты, возвращаемые API, представлены с использованием трех основных типов:

  • Record
  • RecordField
  • Value.

Несколько упрощенно, Record - это список RecordField, RecordField является меткой, а Value и Value могут быть одной из многих вещей, включая Int64, String, Record или List.Кортежи типа (Int, Text) имеют специальные обозначения в DAML, но представлены как обычные Record объекты в API.

Предполагается, что вы используете типы, скомпилированные из определений protobuf, и получили в свои руки com.digitalasset.ledger.api.v1.ValueOuterClass.Value, представляющий [(Int, Text)], вам нужно сделать следующее:

  1. Используйте Value::getList и ValueOuterClass.List::getElementsList, чтобы развернуть Value в List<Value>.
  2. Разверните каждый Value в списке с помощью Value::getRecord, чтобы получить List<Record>
  3. Извлеките два поля каждой записи, используя Record::getFields, чтобы получить List<Pair<RecordField, RecordField>>
  4. Извлеките значения из RecordFields с RecordFields::getValue, давая List<Pair<Value, Value>>
  5. Извлеките Int64, который является псевдонимом для long и String из Value объектов, чтобы получить окончательный List<Pair<Long, String>>

Шаги 2. - 4. могут быть выполнены аккуратно с использованием потокового интерфейса Java.Показанный код предназначен для необработанных типов gRPC, начиная с com.digitalasset.ledger.api.v1.ValueOuterClass.Value:

import com.digitalasset.ledger.api.v1.ValueOuterClass;
import static java.util.AbstractMap.SimpleImmutableEntry;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Demo {
    static SimpleImmutableEntry<ValueOuterClass.RecordField, ValueOuterClass.RecordField> EntryFromTuple(ValueOuterClass.Record tupleRecord) {
        return new SimpleImmutableEntry<>(tupleRecord.getFields(0), tupleRecord.getFields(1));
    }

    static class SimpleImmutableEntryMap<S, T, U, V> implements Function<SimpleImmutableEntry<S, T>, SimpleImmutableEntry<U, V>> {
        Function<S, U> mapFst;
        Function<T, V> mapSnd;

        public SimpleImmutableEntryMap(Function<S, U> mapFst, Function<T, V> mapSnd) {
            this.mapFst = mapFst;
            this.mapSnd = mapSnd;
        }

        @Override
        public SimpleImmutableEntry<U, V> apply(SimpleImmutableEntry<S, T> stEntry) {
            return new SimpleImmutableEntry<> (mapFst.apply(stEntry.getKey()), mapSnd.apply(stEntry.getValue()));
        }
    }

    static List<SimpleImmutableEntry<Long, String>> mapTuple(ValueOuterClass.Value v) {
        return v.getList().getElementsList().stream()
                .map(ValueOuterClass.Value::getRecord)
                .map(Demo::EntryFromTuple)
                .map(new SimpleImmutableEntryMap<>(ValueOuterClass.RecordField::getValue, ValueOuterClass.RecordField::getValue))
                .map(new SimpleImmutableEntryMap<>(ValueOuterClass.Value::getInt64, ValueOuterClass.Value::getText))
                .collect(Collectors.toList());
    }
}
...