sui_graphql_rpc/types/
display.rs1use async_graphql::*;
5
6use diesel::{ExpressionMethods, OptionalExtension, QueryDsl};
7use diesel_async::scoped_futures::ScopedFutureExt;
8use move_core_types::annotated_value as A;
9use sui_display::v1::Format;
10use sui_indexer::{models::display::StoredDisplay, schema::display};
11use sui_types::TypeTag;
12
13use crate::{
14 data::{Db, DbConnection, QueryExecutor},
15 error::Error,
16};
17
18pub(crate) struct Display {
19 pub stored: StoredDisplay,
20}
21
22const MAX_DEPTH: usize = 10;
24
25const MAX_OUTPUT_SIZE: usize = 1024 * 1024;
27
28#[derive(Debug, SimpleObject)]
32pub(crate) struct DisplayEntry {
33 pub key: String,
35 pub value: Option<String>,
37 pub error: Option<String>,
39}
40
41impl Display {
42 pub(crate) async fn query(db: &Db, type_: TypeTag) -> Result<Option<Display>, Error> {
44 let stored: Option<StoredDisplay> = db
45 .execute(move |conn| {
46 async move {
47 conn.first(move || {
48 use display::dsl;
49 dsl::display.filter(
50 dsl::object_type.eq(type_.to_canonical_string(true)),
51 )
52 })
53 .await
54 .optional()
55 }
56 .scope_boxed()
57 })
58 .await?;
59
60 Ok(stored.map(|stored| Display { stored }))
61 }
62
63 pub(crate) fn render(
65 &self,
66 bytes: &[u8],
67 layout: &A::MoveTypeLayout,
68 ) -> Result<Vec<DisplayEntry>, Error> {
69 let fields = self
70 .stored
71 .to_display_update_event()
72 .map_err(|e| Error::Internal(e.to_string()))?
73 .fields;
74
75 let mut rendered = vec![];
76 for (field, value) in Format::parse(MAX_DEPTH, &fields)
77 .map_err(|e| Error::Client(e.to_string()))?
78 .display(MAX_OUTPUT_SIZE, bytes, layout)
79 .map_err(|e| Error::Client(e.to_string()))?
80 {
81 rendered.push(match value {
82 Ok(v) => DisplayEntry::create_value(field, v),
83 Err(e) => DisplayEntry::create_error(field, e.to_string()),
84 });
85 }
86
87 Ok(rendered)
88 }
89}
90
91impl DisplayEntry {
92 pub(crate) fn create_value(key: String, value: String) -> Self {
93 Self {
94 key,
95 value: Some(value),
96 error: None,
97 }
98 }
99
100 pub(crate) fn create_error(key: String, error: String) -> Self {
101 Self {
102 key,
103 value: None,
104 error: Some(error),
105 }
106 }
107}