Skip to content

Commit 3ef2028

Browse files
committed
export IDL type objects; add the idlService and idlInitArgs exports; deprecate the factory functions
1 parent 3721557 commit 3ef2028

32 files changed

+966
-39
lines changed

rust/candid_parser/src/bindings/javascript.rs

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,27 @@ fn pp_defs<'a>(
193193
env: &'a TypeEnv,
194194
def_list: &'a [&'a str],
195195
recs: &'a BTreeSet<&'a str>,
196+
export: bool,
196197
) -> RcDoc<'a> {
197-
let recs_doc = lines(
198-
recs.iter()
199-
.map(|id| kwd("const").append(ident(id)).append(" = IDL.Rec();")),
200-
);
198+
let export_prefix = if export { str("export ") } else { RcDoc::nil() };
199+
200+
let recs_doc = lines(recs.iter().map(|id| {
201+
export_prefix
202+
.clone()
203+
.append(kwd("const"))
204+
.append(ident(id))
205+
.append(" = IDL.Rec();")
206+
}));
201207
let defs = lines(def_list.iter().map(|&id| {
202208
let ty = env.find_type(&id.into()).unwrap();
203209
if recs.contains(id) {
204210
ident(id)
205211
.append(".fill")
206212
.append(enclose("(", pp_ty(ty), ");"))
207213
} else {
208-
kwd("const")
214+
export_prefix
215+
.clone()
216+
.append(kwd("const"))
209217
.append(ident(id))
210218
.append(" = ")
211219
.append(pp_ty(ty))
@@ -230,39 +238,87 @@ fn pp_actor<'a>(ty: &'a Type, recs: &'a BTreeSet<&'a str>) -> RcDoc<'a> {
230238
}
231239
}
232240

241+
pub fn pp_deprecation_comment<'a>() -> RcDoc<'a> {
242+
str("/**").append(RcDoc::hardline())
243+
.append(" * @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.")
244+
.append(RcDoc::hardline())
245+
.append(" */")
246+
.append(RcDoc::hardline())
247+
}
248+
233249
pub fn compile(env: &TypeEnv, actor: &Option<Type>) -> String {
234250
match actor {
235251
None => {
236252
let def_list: Vec<_> = env.to_sorted_iter().map(|pair| pair.0.as_str()).collect();
237253
let recs = infer_rec(env, &def_list).unwrap();
238-
let doc = pp_defs(env, &def_list, &recs);
239-
doc.pretty(LINE_WIDTH).to_string()
254+
let import_doc = str("import { IDL } from '@dfinity/candid';");
255+
let doc = pp_defs(env, &def_list, &recs, true);
256+
let result = import_doc
257+
.append(RcDoc::hardline())
258+
.append(RcDoc::hardline())
259+
.append(doc)
260+
.pretty(LINE_WIDTH)
261+
.to_string();
262+
263+
result
240264
}
241265
Some(actor) => {
242266
let def_list = chase_actor(env, actor).unwrap();
243267
let recs = infer_rec(env, &def_list).unwrap();
244-
let defs = pp_defs(env, &def_list, &recs);
245268
let types = if let TypeInner::Class(ref args, _) = actor.as_ref() {
246269
args.iter().map(|arg| arg.typ.clone()).collect::<Vec<_>>()
247270
} else {
248271
Vec::new()
249272
};
250273
let init = types.as_slice();
251-
let actor = kwd("return").append(pp_actor(actor, &recs)).append(";");
252-
let body = defs.append(actor);
253-
let doc = str("export const idlFactory = ({ IDL }) => ")
254-
.append(enclose_space("{", body, "};"));
255-
// export init args
256-
let init_defs = chase_types(env, init).unwrap();
274+
let init_types: Vec<Type> = init.iter().map(|a| a.clone()).collect();
275+
276+
let import_doc = str("import { IDL } from '@dfinity/candid';");
277+
let defs = pp_defs(env, &def_list, &recs, true);
278+
let actor = pp_actor(actor, &recs);
279+
280+
let idl_service = str("export const idlService = ")
281+
.append(actor.clone())
282+
.append(";");
283+
284+
let idl_init_args = str("export const idlInitArgs = ")
285+
.append(pp_rets(&init_types))
286+
.append(";");
287+
288+
let idl_factory_return = kwd("return").append(actor).append(";");
289+
let idl_factory_body = pp_defs(env, &def_list, &recs, false).append(idl_factory_return);
290+
let idl_factory_doc = pp_deprecation_comment()
291+
.append(str("export const idlFactory = ({ IDL }) => "))
292+
.append(enclose_space("{", idl_factory_body, "};"));
293+
294+
let init_defs = chase_types(env, &init_types).unwrap();
257295
let init_recs = infer_rec(env, &init_defs).unwrap();
258-
let init_defs_doc = pp_defs(env, &init_defs, &init_recs);
259-
let init_doc = kwd("return").append(pp_rets(init)).append(";");
296+
let init_defs_refs: Vec<&str> = init_defs.iter().map(|s| *s).collect();
297+
let init_defs_doc = pp_defs(env, &init_defs_refs, &init_recs, false);
298+
let init_doc = kwd("return").append(pp_rets(&init_types)).append(";");
260299
let init_doc = init_defs_doc.append(init_doc);
261-
let init_doc =
262-
str("export const init = ({ IDL }) => ").append(enclose_space("{", init_doc, "};"));
300+
let init_doc = pp_deprecation_comment()
301+
.append(str("export const init = ({ IDL }) => "))
302+
.append(enclose_space("{", init_doc, "};"));
263303
let init_doc = init_doc.pretty(LINE_WIDTH).to_string();
264-
let doc = doc.append(RcDoc::hardline()).append(init_doc);
265-
doc.pretty(LINE_WIDTH).to_string()
304+
305+
let result = import_doc
306+
.append(RcDoc::hardline())
307+
.append(RcDoc::hardline())
308+
.append(defs)
309+
.append(RcDoc::hardline())
310+
.append(idl_service)
311+
.append(RcDoc::hardline())
312+
.append(RcDoc::hardline())
313+
.append(idl_init_args)
314+
.append(RcDoc::hardline())
315+
.append(RcDoc::hardline())
316+
.append(idl_factory_doc)
317+
.append(RcDoc::hardline())
318+
.append(RcDoc::hardline())
319+
.append(init_doc);
320+
321+
result.pretty(LINE_WIDTH).to_string()
266322
}
267323
}
268324
}

rust/candid_parser/src/bindings/typescript.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::javascript::{ident, is_tuple_fields};
1+
use super::javascript::{ident, is_tuple_fields, pp_deprecation_comment};
22
use crate::syntax::{self, IDLMergedProg, IDLType};
33
use candid::pretty::utils::*;
44
use candid::types::{Field, Function, Label, SharedLabel, Type, TypeEnv, TypeInner};
@@ -317,9 +317,9 @@ fn pp_actor<'a>(env: &'a TypeEnv, ty: &'a Type, syntax: Option<&'a IDLType>) ->
317317
}
318318

319319
pub fn compile(env: &TypeEnv, actor: &Option<Type>, prog: &IDLMergedProg) -> String {
320-
let header = r#"import type { Principal } from '@dfinity/principal';
321-
import type { ActorMethod } from '@dfinity/agent';
320+
let header = r#"import type { ActorMethod } from '@dfinity/agent';
322321
import type { IDL } from '@dfinity/candid';
322+
import type { Principal } from '@dfinity/principal';
323323
"#;
324324
let syntax_actor = prog.resolve_actor().ok().flatten();
325325
let def_list: Vec<_> = env.to_sorted_iter().map(|pair| pair.0.as_str()).collect();
@@ -333,8 +333,14 @@ import type { IDL } from '@dfinity/candid';
333333
.unwrap_or(RcDoc::nil());
334334
docs.append(pp_actor(env, actor, syntax_actor.as_ref().map(|s| &s.typ)))
335335
.append(RcDoc::line())
336+
.append("export declare const idlService: IDL.ServiceClass;")
337+
.append(RcDoc::line())
338+
.append("export declare const idlInitArgs: IDL.Type[];")
339+
.append(RcDoc::line())
340+
.append(pp_deprecation_comment())
336341
.append("export declare const idlFactory: IDL.InterfaceFactory;")
337342
.append(RcDoc::line())
343+
.append(pp_deprecation_comment())
338344
.append("export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];")
339345
}
340346
};

rust/candid_parser/tests/assets/ok/actor.d.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Principal } from '@dfinity/principal';
21
import type { ActorMethod } from '@dfinity/agent';
32
import type { IDL } from '@dfinity/candid';
3+
import type { Principal } from '@dfinity/principal';
44

55
export type f = ActorMethod<[number], number>;
66
export type g = f;
@@ -13,5 +13,13 @@ export interface _SERVICE {
1313
'h2' : h,
1414
'o' : ActorMethod<[o], o>,
1515
}
16+
export declare const idlService: IDL.ServiceClass;
17+
export declare const idlInitArgs: IDL.Type[];
18+
/**
19+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
20+
*/
1621
export declare const idlFactory: IDL.InterfaceFactory;
22+
/**
23+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
24+
*/
1725
export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];

rust/candid_parser/tests/assets/ok/actor.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
import { IDL } from '@dfinity/candid';
2+
3+
export const o = IDL.Rec();
4+
export const f = IDL.Func([IDL.Int8], [IDL.Int8], []);
5+
export const h = IDL.Func([f], [f], []);
6+
export const g = f;
7+
o.fill(IDL.Opt(o));
8+
9+
export const idlService = IDL.Service({
10+
'f' : IDL.Func([IDL.Nat], [h], []),
11+
'g' : f,
12+
'h' : g,
13+
'h2' : h,
14+
'o' : IDL.Func([o], [o], []),
15+
});
16+
17+
export const idlInitArgs = [];
18+
19+
/**
20+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
21+
*/
122
export const idlFactory = ({ IDL }) => {
223
const o = IDL.Rec();
324
const f = IDL.Func([IDL.Int8], [IDL.Int8], []);
@@ -12,4 +33,8 @@ export const idlFactory = ({ IDL }) => {
1233
'o' : IDL.Func([o], [o], []),
1334
});
1435
};
36+
37+
/**
38+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
39+
*/
1540
export const init = ({ IDL }) => { return []; };

rust/candid_parser/tests/assets/ok/class.d.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Principal } from '@dfinity/principal';
21
import type { ActorMethod } from '@dfinity/agent';
32
import type { IDL } from '@dfinity/candid';
3+
import type { Principal } from '@dfinity/principal';
44

55
export type List = [] | [[bigint, List]];
66
export interface Profile { 'age' : number, 'name' : string }
@@ -14,5 +14,13 @@ export interface _SERVICE {
1414
'get' : ActorMethod<[], List>,
1515
'set' : ActorMethod<[List], List>,
1616
}
17+
export declare const idlService: IDL.ServiceClass;
18+
export declare const idlInitArgs: IDL.Type[];
19+
/**
20+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
21+
*/
1722
export declare const idlFactory: IDL.InterfaceFactory;
23+
/**
24+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
25+
*/
1826
export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];

rust/candid_parser/tests/assets/ok/class.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
import { IDL } from '@dfinity/candid';
2+
3+
export const List = IDL.Rec();
4+
List.fill(IDL.Opt(IDL.Tuple(IDL.Int, List)));
5+
export const Profile = IDL.Record({ 'age' : IDL.Nat8, 'name' : IDL.Text });
6+
7+
export const idlService = IDL.Service({
8+
'get' : IDL.Func([], [List], []),
9+
'set' : IDL.Func([List], [List], []),
10+
});
11+
12+
export const idlInitArgs = [IDL.Int, List, Profile];
13+
14+
/**
15+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
16+
*/
117
export const idlFactory = ({ IDL }) => {
218
const List = IDL.Rec();
319
List.fill(IDL.Opt(IDL.Tuple(IDL.Int, List)));
@@ -7,6 +23,10 @@ export const idlFactory = ({ IDL }) => {
723
'set' : IDL.Func([List], [List], []),
824
});
925
};
26+
27+
/**
28+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
29+
*/
1030
export const init = ({ IDL }) => {
1131
const List = IDL.Rec();
1232
List.fill(IDL.Opt(IDL.Tuple(IDL.Int, List)));

rust/candid_parser/tests/assets/ok/comment.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Principal } from '@dfinity/principal';
21
import type { ActorMethod } from '@dfinity/agent';
32
import type { IDL } from '@dfinity/candid';
3+
import type { Principal } from '@dfinity/principal';
44

55
/**
66
* line comment
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
const id = IDL.Nat8;
1+
import { IDL } from '@dfinity/candid';
2+
3+
export const id = IDL.Nat8;
24

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Principal } from '@dfinity/principal';
21
import type { ActorMethod } from '@dfinity/agent';
32
import type { IDL } from '@dfinity/candid';
3+
import type { Principal } from '@dfinity/principal';
44

55
export type A = [] | [B];
66
export type B = [] | [C];
@@ -9,5 +9,13 @@ export type X = Y;
99
export type Y = Z;
1010
export type Z = A;
1111
export interface _SERVICE { 'f' : ActorMethod<[A, B, C, X, Y, Z], undefined> }
12+
export declare const idlService: IDL.ServiceClass;
13+
export declare const idlInitArgs: IDL.Type[];
14+
/**
15+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
16+
*/
1217
export declare const idlFactory: IDL.InterfaceFactory;
18+
/**
19+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
20+
*/
1321
export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];

rust/candid_parser/tests/assets/ok/cyclic.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
import { IDL } from '@dfinity/candid';
2+
3+
export const A = IDL.Rec();
4+
export const C = A;
5+
export const B = IDL.Opt(C);
6+
A.fill(IDL.Opt(B));
7+
export const Z = A;
8+
export const Y = Z;
9+
export const X = Y;
10+
11+
export const idlService = IDL.Service({
12+
'f' : IDL.Func([A, B, C, X, Y, Z], [], []),
13+
});
14+
15+
export const idlInitArgs = [];
16+
17+
/**
18+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
19+
*/
120
export const idlFactory = ({ IDL }) => {
221
const A = IDL.Rec();
322
const C = A;
@@ -8,4 +27,8 @@ export const idlFactory = ({ IDL }) => {
827
const X = Y;
928
return IDL.Service({ 'f' : IDL.Func([A, B, C, X, Y, Z], [], []) });
1029
};
30+
31+
/**
32+
* @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.
33+
*/
1134
export const init = ({ IDL }) => { return []; };

0 commit comments

Comments
 (0)