Skip to content

Commit e52a537

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

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
@@ -201,19 +201,27 @@ fn pp_defs<'a>(
201201
env: &'a TypeEnv,
202202
def_list: &'a [&'a str],
203203
recs: &'a BTreeSet<&'a str>,
204+
export: bool,
204205
) -> RcDoc<'a> {
205-
let recs_doc = lines(
206-
recs.iter()
207-
.map(|id| kwd("const").append(ident(id)).append(" = IDL.Rec();")),
208-
);
206+
let export_prefix = if export { str("export ") } else { RcDoc::nil() };
207+
208+
let recs_doc = lines(recs.iter().map(|id| {
209+
export_prefix
210+
.clone()
211+
.append(kwd("const"))
212+
.append(ident(id))
213+
.append(" = IDL.Rec();")
214+
}));
209215
let defs = lines(def_list.iter().map(|&id| {
210216
let ty = env.find_type(&id.into()).unwrap();
211217
if recs.contains(id) {
212218
ident(id)
213219
.append(".fill")
214220
.append(enclose("(", pp_ty(ty), ");"))
215221
} else {
216-
kwd("const")
222+
export_prefix
223+
.clone()
224+
.append(kwd("const"))
217225
.append(ident(id))
218226
.append(" = ")
219227
.append(pp_ty(ty))
@@ -238,39 +246,87 @@ fn pp_actor<'a>(ty: &'a Type, recs: &'a BTreeSet<&'a str>) -> RcDoc<'a> {
238246
}
239247
}
240248

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

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.to_sorted_iter().map(|pair| pair.0.as_str()).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)