Skip to content

Commit f25c3b7

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

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
@@ -200,19 +200,27 @@ fn pp_defs<'a>(
200200
env: &'a TypeEnv,
201201
def_list: &'a [&'a str],
202202
recs: &'a BTreeSet<&'a str>,
203+
export: bool,
203204
) -> RcDoc<'a> {
204-
let recs_doc = lines(
205-
recs.iter()
206-
.map(|id| kwd("const").append(ident(id)).append(" = IDL.Rec();")),
207-
);
205+
let export_prefix = if export { str("export ") } else { RcDoc::nil() };
206+
207+
let recs_doc = lines(recs.iter().map(|id| {
208+
export_prefix
209+
.clone()
210+
.append(kwd("const"))
211+
.append(ident(id))
212+
.append(" = IDL.Rec();")
213+
}));
208214
let defs = lines(def_list.iter().map(|id| {
209215
let ty = env.find_type(id).unwrap();
210216
if recs.contains(id) {
211217
ident(id)
212218
.append(".fill")
213219
.append(enclose("(", pp_ty(ty), ");"))
214220
} else {
215-
kwd("const")
221+
export_prefix
222+
.clone()
223+
.append(kwd("const"))
216224
.append(ident(id))
217225
.append(" = ")
218226
.append(pp_ty(ty))
@@ -237,38 +245,86 @@ fn pp_actor<'a>(ty: &'a Type, recs: &'a BTreeSet<&'a str>) -> RcDoc<'a> {
237245
}
238246
}
239247

248+
pub fn pp_deprecation_comment<'a>() -> RcDoc<'a> {
249+
str("/**").append(RcDoc::hardline())
250+
.append(" * @deprecated Since `@dfinity/candid` v3.2.1, you can import IDL types directly from this module instead of using this factory function.")
251+
.append(RcDoc::hardline())
252+
.append(" */")
253+
.append(RcDoc::hardline())
254+
}
255+
240256
pub fn compile(env: &TypeEnv, actor: &Option<Type>) -> String {
241257
match actor {
242258
None => {
243259
let def_list: Vec<_> = env.0.iter().map(|pair| pair.0.as_ref()).collect();
244260
let recs = infer_rec(env, &def_list).unwrap();
245-
let doc = pp_defs(env, &def_list, &recs);
246-
doc.pretty(LINE_WIDTH).to_string()
261+
let import_doc = str("import { IDL } from '@dfinity/candid';");
262+
let doc = pp_defs(env, &def_list, &recs, true);
263+
let result = import_doc
264+
.append(RcDoc::hardline())
265+
.append(RcDoc::hardline())
266+
.append(doc)
267+
.pretty(LINE_WIDTH)
268+
.to_string();
269+
270+
result
247271
}
248272
Some(actor) => {
249273
let def_list = chase_actor(env, actor).unwrap();
250274
let recs = infer_rec(env, &def_list).unwrap();
251-
let defs = pp_defs(env, &def_list, &recs);
252275
let init = if let TypeInner::Class(ref args, _) = actor.as_ref() {
253276
args.as_slice()
254277
} else {
255278
&[][..]
256279
};
257-
let actor = kwd("return").append(pp_actor(actor, &recs)).append(";");
258-
let body = defs.append(actor);
259-
let doc = str("export const idlFactory = ({ IDL }) => ")
260-
.append(enclose_space("{", body, "};"));
261-
// export init args
262-
let init_defs = chase_types(env, init).unwrap();
280+
let init_types: Vec<Type> = init.iter().map(|a| a.clone()).collect();
281+
282+
let import_doc = str("import { IDL } from '@dfinity/candid';");
283+
let defs = pp_defs(env, &def_list, &recs, true);
284+
let actor = pp_actor(actor, &recs);
285+
286+
let idl_service = str("export const idlService = ")
287+
.append(actor.clone())
288+
.append(";");
289+
290+
let idl_init_args = str("export const idlInitArgs = ")
291+
.append(pp_rets(&init_types))
292+
.append(";");
293+
294+
let idl_factory_return = kwd("return").append(actor).append(";");
295+
let idl_factory_body = pp_defs(env, &def_list, &recs, false).append(idl_factory_return);
296+
let idl_factory_doc = pp_deprecation_comment()
297+
.append(str("export const idlFactory = ({ IDL }) => "))
298+
.append(enclose_space("{", idl_factory_body, "};"));
299+
300+
let init_defs = chase_types(env, &init_types).unwrap();
263301
let init_recs = infer_rec(env, &init_defs).unwrap();
264-
let init_defs_doc = pp_defs(env, &init_defs, &init_recs);
265-
let init_doc = kwd("return").append(pp_rets(init)).append(";");
302+
let init_defs_refs: Vec<&str> = init_defs.iter().map(|s| *s).collect();
303+
let init_defs_doc = pp_defs(env, &init_defs_refs, &init_recs, false);
304+
let init_doc = kwd("return").append(pp_rets(&init_types)).append(";");
266305
let init_doc = init_defs_doc.append(init_doc);
267-
let init_doc =
268-
str("export const init = ({ IDL }) => ").append(enclose_space("{", init_doc, "};"));
306+
let init_doc = pp_deprecation_comment()
307+
.append(str("export const init = ({ IDL }) => "))
308+
.append(enclose_space("{", init_doc, "};"));
269309
let init_doc = init_doc.pretty(LINE_WIDTH).to_string();
270-
let doc = doc.append(RcDoc::hardline()).append(init_doc);
271-
doc.pretty(LINE_WIDTH).to_string()
310+
311+
let result = import_doc
312+
.append(RcDoc::hardline())
313+
.append(RcDoc::hardline())
314+
.append(defs)
315+
.append(RcDoc::hardline())
316+
.append(idl_service)
317+
.append(RcDoc::hardline())
318+
.append(RcDoc::hardline())
319+
.append(idl_init_args)
320+
.append(RcDoc::hardline())
321+
.append(RcDoc::hardline())
322+
.append(idl_factory_doc)
323+
.append(RcDoc::hardline())
324+
.append(RcDoc::hardline())
325+
.append(init_doc);
326+
327+
result.pretty(LINE_WIDTH).to_string()
272328
}
273329
}
274330
}

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};
@@ -319,9 +319,9 @@ fn pp_actor<'a>(env: &'a TypeEnv, ty: &'a Type, syntax: Option<&'a IDLType>) ->
319319
}
320320

321321
pub fn compile(env: &TypeEnv, actor: &Option<Type>, prog: &IDLMergedProg) -> String {
322-
let header = r#"import type { Principal } from '@dfinity/principal';
323-
import type { ActorMethod } from '@dfinity/agent';
322+
let header = r#"import type { ActorMethod } from '@dfinity/agent';
324323
import type { IDL } from '@dfinity/candid';
324+
import type { Principal } from '@dfinity/principal';
325325
"#;
326326
let syntax_actor = prog.resolve_actor().ok().flatten();
327327
let def_list: Vec<_> = env.0.iter().map(|pair| pair.0.as_ref()).collect();
@@ -335,8 +335,14 @@ import type { IDL } from '@dfinity/candid';
335335
.unwrap_or(RcDoc::nil());
336336
docs.append(pp_actor(env, actor, syntax_actor.as_ref().map(|s| &s.typ)))
337337
.append(RcDoc::line())
338+
.append("export declare const idlService: IDL.ServiceClass;")
339+
.append(RcDoc::line())
340+
.append("export declare const idlInitArgs: IDL.Type[];")
341+
.append(RcDoc::line())
342+
.append(pp_deprecation_comment())
338343
.append("export declare const idlFactory: IDL.InterfaceFactory;")
339344
.append(RcDoc::line())
345+
.append(pp_deprecation_comment())
340346
.append("export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];")
341347
}
342348
};

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)