如何将通过 DA Ledger API 收到的 DAML 元组转换为 Java 对?
How do I convert DAML tuples received via the DA Ledger API into Java pairs?
我编写了一个生成元组列表的 DAML 模型,例如[(Int, Text)]
。我通过 DA Ledger API 收到此数据 - 如何将其转换为 Java 中的 List<Pair<Long, String>>
?
Java 取决于您使用的是原始编译的 Protobuf 类型,还是 Java 语言绑定提供的包装类型。
API 返回的对象使用三种主要类型表示:
Record
RecordField
Value
.
稍微简化一下,aRecord
是 RecordField
的列表,a RecordField
是标签,a Value
和 a Value
可以是一个许多事情,包括 Int64
、String
、Record
或 List
。像 (Int, Text)
这样的元组在 DAML 中有特殊的表示法,但在 API.
中表示为普通的 Record
对象
假设您正在使用从 protobuf 定义编译的类型,并且已经掌握了代表 [(Int, Text)]
的 com.digitalasset.ledger.api.v1.ValueOuterClass.Value
,您需要执行以下操作:
- 使用
Value::getList
和 ValueOuterClass.List::getElementsList
将 Value
解包为 List<Value>
。
- 通过
Value::getRecord
展开列表中的每个 Value
以获得 List<Record>
- 使用
Record::getFields
提取每条记录的两个字段得到List<Pair<RecordField, RecordField>>
- 使用
RecordFields::getValue
从 RecordFields
中提取值,给出 List<Pair<Value, Value>>
- 从
Value
对象中提取Int64
,它是long
的别名,和String
得到最终的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());
}
}
假设您有以下 daml 模板:
template ListOfTuples
with
party : Party
listOfTuples : [(Int, Text)]
where
signatory party
已转换为 com.daml.ledger.javaapi.data.Record
java api,您可以将列表中的元组也视为 List<Pair<Long, String>>
,从而将其转换为 List<Pair<Long, String>>
=14=]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());
}
我编写了一个生成元组列表的 DAML 模型,例如[(Int, Text)]
。我通过 DA Ledger API 收到此数据 - 如何将其转换为 Java 中的 List<Pair<Long, String>>
?
Java 取决于您使用的是原始编译的 Protobuf 类型,还是 Java 语言绑定提供的包装类型。
API 返回的对象使用三种主要类型表示:
Record
RecordField
Value
.
稍微简化一下,aRecord
是 RecordField
的列表,a RecordField
是标签,a Value
和 a Value
可以是一个许多事情,包括 Int64
、String
、Record
或 List
。像 (Int, Text)
这样的元组在 DAML 中有特殊的表示法,但在 API.
Record
对象
假设您正在使用从 protobuf 定义编译的类型,并且已经掌握了代表 [(Int, Text)]
的 com.digitalasset.ledger.api.v1.ValueOuterClass.Value
,您需要执行以下操作:
- 使用
Value::getList
和ValueOuterClass.List::getElementsList
将Value
解包为List<Value>
。 - 通过
Value::getRecord
展开列表中的每个Value
以获得List<Record>
- 使用
Record::getFields
提取每条记录的两个字段得到List<Pair<RecordField, RecordField>>
- 使用
RecordFields::getValue
从RecordFields
中提取值,给出List<Pair<Value, Value>>
- 从
Value
对象中提取Int64
,它是long
的别名,和String
得到最终的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());
}
}
假设您有以下 daml 模板:
template ListOfTuples
with
party : Party
listOfTuples : [(Int, Text)]
where
signatory party
已转换为 com.daml.ledger.javaapi.data.Record
java api,您可以将列表中的元组也视为 List<Pair<Long, String>>
,从而将其转换为 List<Pair<Long, String>>
=14=]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());
}