1mod generated;
2pub mod json_rpc;
3
4pub use generated::*;
5
6mod compiletest {}
37
38#[cfg(test)]
40#[cfg(all(not(feature = "url"), not(feature = "fluent-uri")))]
41mod test {
42 #![allow(deprecated)]
43 use std::{
44 borrow::Cow,
45 collections::{HashMap, HashSet},
46 };
47
48 use serde_json::json;
49
50 use crate::*;
51
52 #[test]
53 fn nullable_field() {
54 let tdro = TextDocumentRegistrationOptions {
55 document_selector: None,
56 };
57 let tdro_str = serde_json::to_string(&tdro).unwrap();
58 assert_eq!(tdro_str, r#"{"documentSelector":null}"#);
59
60 let tdro = serde_json::from_str::<TextDocumentRegistrationOptions>(&tdro_str).unwrap();
61 assert_eq!(
62 tdro,
63 TextDocumentRegistrationOptions {
64 document_selector: None
65 }
66 );
67
68 assert_eq!(tdro, serde_json::from_str("{}").unwrap());
71 }
72
73 #[test]
74 fn nullable_field_default() {
75 let ip = InitializeParams::default();
76
77 let ip_str = serde_json::to_string(&ip).unwrap();
78
79 assert_eq!(
80 ip_str,
81 r#"{"processId":null,"rootUri":null,"capabilities":{}}"#
82 );
83
84 assert_eq!(
85 InitializeParams::default(),
86 serde_json::from_str(&ip_str).unwrap()
87 );
88
89 let bad_ip_str = r#"{"rootUri":null,"capabilities":{}}"#;
92 assert_eq!(
93 InitializeParams::default(),
94 serde_json::from_str(bad_ip_str).unwrap()
95 );
96 }
97
98 #[test]
99 fn optional_field() {
100 let cp = ColorPresentation {
101 label: "Label".to_string(),
102 text_edit: None,
103 ..Default::default()
104 };
105 let cp_str = serde_json::to_string(&cp).unwrap();
106 assert_eq!(cp_str, r#"{"label":"Label"}"#);
107
108 let cp = serde_json::from_str::<ColorPresentation>(&cp_str).unwrap();
109 assert_eq!(
110 cp,
111 ColorPresentation {
112 label: "Label".to_string(),
113 text_edit: None,
114 ..Default::default()
115 }
116 );
117 assert_eq!(
120 serde_json::from_str::<ColorPresentation>(r#"{"label":"Label","textEdit":null}"#)
121 .unwrap(),
122 cp
123 );
124 }
125
126 #[test]
127 fn optional_nullable_field() {
128 let wfip = WorkspaceFoldersInitializeParams {
129 workspace_folders: None,
130 };
131
132 let wfip_str = serde_json::to_string(&wfip).unwrap();
133
134 assert_eq!(wfip_str, r"{}");
135
136 assert_eq!(
137 serde_json::from_str::<WorkspaceFoldersInitializeParams>(&wfip_str).unwrap(),
138 wfip
139 );
140
141 let wfip = WorkspaceFoldersInitializeParams {
142 workspace_folders: Some(crate::WorkspaceFolders::Null),
143 };
144 let wfip_str = serde_json::to_string(&wfip).unwrap();
145 assert_eq!(wfip_str, r#"{"workspaceFolders":null}"#);
146 assert_eq!(
147 serde_json::from_str::<WorkspaceFoldersInitializeParams>(&wfip_str).unwrap(),
148 wfip
149 );
150
151 let wfip = WorkspaceFoldersInitializeParams {
152 workspace_folders: Some(crate::WorkspaceFolders::WorkspaceFolderList(Vec::new())),
153 };
154 let wfip_str = serde_json::to_string(&wfip).unwrap();
155 assert_eq!(wfip_str, r#"{"workspaceFolders":[]}"#);
156 assert_eq!(
157 serde_json::from_str::<WorkspaceFoldersInitializeParams>(&wfip_str).unwrap(),
158 wfip
159 );
160 }
161
162 #[test]
163 fn derives() {
164 let pos = Position::default();
165 let table = HashMap::from([(pos, 123)]);
166 assert_eq!(table.get(&pos), Some(&123));
167
168 let range = Range::default();
169 let table = HashSet::from([range]);
170 assert!(table.contains(&range));
171
172 let doc_sym = DocumentSymbol {
173 kind: crate::SymbolKind::Function,
174 name: String::default(),
175 detail: Option::default(),
176 tags: Option::default(),
177 deprecated: Option::default(),
178 range: Range::default(),
179 selection_range: Range::default(),
180 children: Option::default(),
181 };
182 let table = HashSet::from([doc_sym.clone()]);
183 assert!(table.contains(&doc_sym));
184
185 let wfip = WorkspaceFoldersInitializeParams {
187 workspace_folders: Some(Vec::new().into()),
188 };
189 let wfip_str = serde_json::to_string(&wfip).unwrap();
190 assert_eq!(wfip_str, r#"{"workspaceFolders":[]}"#);
191 assert_eq!(
192 serde_json::from_str::<WorkspaceFoldersInitializeParams>(&wfip_str).unwrap(),
193 wfip
194 );
195 assert_eq!(WorkspaceFolders::Null, ().into());
196 let wfip = WorkspaceFoldersInitializeParams {
197 workspace_folders: Some(().into()),
198 };
199 let wfip_str = serde_json::to_string(&wfip).unwrap();
200 assert_eq!(wfip_str, r#"{"workspaceFolders":null}"#);
201 assert_eq!(
202 serde_json::from_str::<WorkspaceFoldersInitializeParams>(&wfip_str).unwrap(),
203 wfip
204 );
205 let wfsc = WorkspaceFoldersServerCapabilities {
206 change_notifications: Some("some-noti-id".into()),
207 ..Default::default()
208 };
209 let wfsc_str = serde_json::to_string(&wfsc).unwrap();
210 assert_eq!(wfsc_str, r#"{"changeNotifications":"some-noti-id"}"#);
211 let wfsc = WorkspaceFoldersServerCapabilities {
212 change_notifications: Some(String::from("some-noti-id").into()),
213 ..Default::default()
214 };
215 let wfsc_str = serde_json::to_string(&wfsc).unwrap();
216 assert_eq!(wfsc_str, r#"{"changeNotifications":"some-noti-id"}"#);
217 let wfsc = WorkspaceFoldersServerCapabilities {
218 change_notifications: Some(false.into()),
219 ..Default::default()
220 };
221 let wfsc_str = serde_json::to_string(&wfsc).unwrap();
222 assert_eq!(wfsc_str, r#"{"changeNotifications":false}"#);
223 let wfsc = WorkspaceFoldersServerCapabilities {
224 change_notifications: Some('f'.into()),
225 ..Default::default()
226 };
227 let wfsc_str = serde_json::to_string(&wfsc).unwrap();
228 assert_eq!(wfsc_str, r#"{"changeNotifications":"f"}"#);
229 let boxed_str: Box<str> = Box::from("foo");
230 let wfsc = WorkspaceFoldersServerCapabilities {
231 change_notifications: Some(boxed_str.into()),
232 ..Default::default()
233 };
234 let wfsc_str = serde_json::to_string(&wfsc).unwrap();
235 assert_eq!(wfsc_str, r#"{"changeNotifications":"foo"}"#);
236 }
237
238 #[test]
239 fn special_impls() {
240 let pos = Position {
241 line: 2,
242 character: 0,
243 };
244 let pos2 = Position {
245 line: 1,
246 character: 9,
247 };
248 assert!(pos2 < pos);
249
250 let pos3 = pos2;
252 assert_eq!(pos3, pos2);
253
254 let range = Range {
255 start: pos2,
256 end: pos,
257 };
258 let range2 = range;
260 assert_eq!(range2, range);
261
262 let range3 = Range {
263 start: Position::default(),
264 end: Position {
265 line: 999,
266 character: 999,
267 },
268 };
269 assert!(range3 < range2);
270
271 let range4 = Range::default();
272 assert!(range4 < range3);
273
274 let method: String = LspRequestMethod::TextDocumentOnTypeFormatting.into();
275 assert_eq!(method, "textDocument/onTypeFormatting");
276 let method = LspRequestMethod::Shutdown.to_string();
277 assert_eq!(method, "shutdown");
278 let method = LspRequestMethod::Custom("foo").to_string();
279 assert_eq!(method, "foo");
280 let method = LspNotificationMethod::Custom("foo").to_string();
281 assert_eq!(method, "foo");
282 let method = LspNotificationMethod::CancelRequest.to_string();
283 assert_eq!(method, "$/cancelRequest");
284 let method = LspNotificationMethod::WorkspaceDidChangeWatchedFiles.to_string();
285 assert_eq!(method, "workspace/didChangeWatchedFiles");
286
287 let wk = WatchKind::Delete;
288 let wk2 = WatchKind::Create;
289 assert_eq!(wk | wk2, WatchKind::Custom(5));
290 assert_eq!(wk | wk2 | WatchKind::Change, WatchKind::Custom(7));
291 assert_eq!((wk | wk2) & wk, wk);
292 assert_eq!(wk | wk, wk);
293 assert_eq!((wk | wk2 | WatchKind::Change) & (wk | wk2), wk | wk2);
294 assert_eq!(WatchKind::Delete ^ WatchKind::Delete, WatchKind::Custom(0));
295 assert_eq!(WatchKind::Custom(0) ^ WatchKind::Create, WatchKind::Create);
296 let mut wk = WatchKind::Custom(0);
297 wk |= WatchKind::Delete;
298 assert_eq!(wk, WatchKind::Delete);
299 wk &= WatchKind::Create;
300 assert_eq!(wk, WatchKind::Custom(0));
301 wk ^= WatchKind::Delete;
302 assert_eq!(wk, WatchKind::Delete);
303 }
304
305 #[test]
306 fn string_literal_field() {
307 let wdpe = WorkDoneProgressEnd {
308 message: Some("change da world. my final message. goodbye".to_string()),
309 };
310
311 let ser = serde_json::to_string(&wdpe).unwrap();
312 assert_eq!(
313 ser,
314 r#"{"message":"change da world. my final message. goodbye","kind":"end"}"#
315 );
316
317 let deser = serde_json::from_str::<WorkDoneProgressEnd>(&ser).unwrap();
318 assert_eq!(deser, wdpe);
319
320 let fake_ser = r#"{"message":"change da world. my final message. goodbye","kind":"begin"}"#;
321 assert!(serde_json::from_str::<WorkDoneProgressEnd>(fake_ser).is_err());
322
323 let doc_change = CreateFile {
324 uri: "file:///foo.txt".to_string().into(),
325 options: None,
326 annotation_id: None,
327 };
328 let ser = serde_json::to_string(&doc_change).unwrap();
329 assert_eq!(ser, r#"{"uri":"file:///foo.txt","kind":"create"}"#);
330
331 let ser = r#"{"uri":"file:///foo.txt","kind":"create"}"#;
332 let deser = serde_json::from_str::<DocumentChange>(ser).unwrap();
333 assert_eq!(deser, doc_change.into());
334 let ser = r#"{"uri":"file:///foo.txt","kind":"delete","annotationId":"foo"}"#;
335 let deser = serde_json::from_str::<DocumentChange>(ser).unwrap();
336 assert_eq!(
337 deser,
338 DocumentChange::DeleteFile(DeleteFile {
339 uri: crate::Uri("file:///foo.txt".to_string()),
340 options: None,
341 annotation_id: Some(String::from("foo"))
342 })
343 );
344 let bad_ser = r#"{"uri":"file:///foo.txt","kind":"delet"}"#;
345 assert!(serde_json::from_str::<DocumentChange>(bad_ser).is_err());
346 }
347
348 #[test]
349 fn string_enum() {
350 let frk = FoldingRangeKind::Comment;
351 let ser = serde_json::to_string(&frk).unwrap();
352
353 assert_eq!(ser, "\"comment\"");
354 assert_eq!(
355 serde_json::from_str::<FoldingRangeKind>(&ser).unwrap(),
356 FoldingRangeKind::Comment
357 );
358
359 let frk = FoldingRangeKind::Custom(Cow::Borrowed("foo"));
360 let ser = serde_json::to_string(&frk).unwrap();
361
362 assert_eq!(ser, "\"foo\"");
363 assert_eq!(
364 serde_json::from_str::<FoldingRangeKind>(&ser).unwrap(),
365 FoldingRangeKind::Custom(Cow::Borrowed("foo"))
366 );
367 assert_eq!("foo", frk.as_str());
368
369 let mk = MarkupKind::PlainText;
370 assert_eq!("\"plaintext\"", serde_json::to_string(&mk).unwrap());
371 assert!(serde_json::from_str::<MarkupKind>("foo").is_err());
372 assert_eq!("plaintext", mk.as_str());
373 }
374
375 #[test]
376 fn str_enum_into() {
377 const CONSTANT: &str = "my_custom_variant";
378 let _parsed: LspNotificationMethod = CONSTANT.into();
379 }
380
381 #[test]
382 fn int_enum() {
383 let sk = SymbolKind::Namespace;
384 let ser = serde_json::to_string(&sk).unwrap();
385
386 assert_eq!(ser, "3");
387 assert_eq!(
388 serde_json::from_str::<SymbolKind>(&ser).unwrap(),
389 SymbolKind::Namespace
390 );
391 assert!(serde_json::from_str::<SymbolKind>("299").is_err());
392
393 let wk = WatchKind::Custom(123);
394 let ser = serde_json::to_string(&wk).unwrap();
395
396 assert_eq!(ser, "123");
397 assert_eq!(wk, serde_json::from_str::<WatchKind>(&ser).unwrap());
398 assert_eq!(
399 WatchKind::Change,
400 serde_json::from_str::<WatchKind>("2").unwrap()
401 );
402 }
403
404 #[test]
405 fn request_object_from_request() {
406 let params = TypeDefinitionParams {
407 work_done_progress_params: crate::WorkDoneProgressParams {
408 work_done_token: None,
409 },
410 partial_result_params: crate::PartialResultParams {
411 partial_result_token: None,
412 },
413 text_document_position_params: crate::TextDocumentPositionParams {
414 text_document: crate::TextDocumentIdentifier { uri: "foo".into() },
415 position: Position::default(),
416 },
417 };
418 let req = json_rpc::RequestObject::from_request::<TypeDefinitionRequest>(
419 json_rpc::Id::Number(123),
420 params.clone(),
421 );
422
423 let ser = serde_json::to_string(&req).unwrap();
424
425 assert_eq!(
426 ser,
427 r#"{"jsonrpc":"2.0","id":123,"method":"textDocument/typeDefinition","params":{"position":{"character":0,"line":0},"textDocument":{"uri":"foo"}}}"#
428 );
429 assert_eq!(req.id(), Some(&json_rpc::Id::Number(123)));
430 assert_eq!(req.method(), "textDocument/typeDefinition");
431 assert_eq!(req.params(), Some(&json!(params)));
432 }
433
434 #[test]
435 fn request_object_from_request_no_params() {
436 let req = json_rpc::RequestObject::from_request::<WorkspaceFoldersRequest>(
437 json_rpc::Id::String("foo".into()),
438 (),
439 );
440
441 let ser = serde_json::to_string(&req).unwrap();
442
443 assert_eq!(
444 ser,
445 r#"{"jsonrpc":"2.0","id":"foo","method":"workspace/workspaceFolders"}"#
446 );
447 }
448
449 #[test]
450 fn request_object_from_notification() {
451 let noti = json_rpc::RequestObject::from_notification::<InitializedNotification>(
452 InitializedParams {},
453 );
454
455 let ser = serde_json::to_string(¬i).unwrap();
456
457 assert_eq!(
458 ser,
459 r#"{"jsonrpc":"2.0","method":"initialized","params":{}}"#
460 );
461 assert_eq!(noti.id(), None);
462 assert_eq!(noti.method(), "initialized");
463 assert_eq!(noti.params(), Some(&json!(InitializedParams {})));
464 }
465
466 #[test]
467 fn request_object_from_notification_no_params() {
468 let noti = json_rpc::RequestObject::from_notification::<ExitNotification>(());
469
470 let ser = serde_json::to_string(¬i).unwrap();
471
472 assert_eq!(ser, r#"{"jsonrpc":"2.0","method":"exit"}"#);
473 }
474
475 #[test]
476 fn response_object_from_success() {
477 let id = json_rpc::Id::Number(123);
478
479 let res = json_rpc::ResponseObject::from_success::<ImplementationRequest>(
480 id.clone(),
481 Some(ImplementationResponse::DefinitionLinkList(Vec::new())),
482 );
483
484 let ser = serde_json::to_string(&res).unwrap();
485 assert_eq!(r#"{"jsonrpc":"2.0","result":[],"id":123}"#, &ser);
486 assert_eq!(res, serde_json::from_str(&ser).unwrap());
487
488 let res = json_rpc::ResponseObject::from_success::<ImplementationRequest>(id.clone(), None);
489
490 let ser = serde_json::to_string(&res).unwrap();
491 assert_eq!(r#"{"jsonrpc":"2.0","result":null,"id":123}"#, &ser);
492 assert_eq!(res, serde_json::from_str(&ser).unwrap());
493
494 let res = json_rpc::ResponseObject::from_success::<ImplementationRequest>(id.clone(), None);
495
496 let ser = serde_json::to_string(&res).unwrap();
497 assert_eq!(r#"{"jsonrpc":"2.0","result":null,"id":123}"#, &ser);
498 assert_eq!(res, serde_json::from_str(&ser).unwrap());
499
500 let res = json_rpc::ResponseObject::from_success::<ShowMessageRequest>(id.clone(), None);
501
502 let ser = serde_json::to_string(&res).unwrap();
503 assert_eq!(r#"{"jsonrpc":"2.0","result":null,"id":123}"#, &ser);
504 assert_eq!(res, serde_json::from_str(&ser).unwrap());
505
506 let res = json_rpc::ResponseObject::from_success::<ShowMessageRequest>(
507 id.clone(),
508 Some(crate::MessageActionItem {
509 title: "foo".into(),
510 }),
511 );
512
513 let ser = serde_json::to_string(&res).unwrap();
514 assert_eq!(
515 r#"{"jsonrpc":"2.0","result":{"title":"foo"},"id":123}"#,
516 &ser
517 );
518 assert_eq!(res, serde_json::from_str(&ser).unwrap());
519
520 let res = json_rpc::ResponseObject::from_success::<CodeLensRefreshRequest>(id, ());
521
522 let ser = serde_json::to_string(&res).unwrap();
523 assert_eq!(r#"{"jsonrpc":"2.0","result":null,"id":123}"#, &ser);
524 assert_eq!(res, serde_json::from_str(&ser).unwrap());
525 }
526
527 #[test]
528 fn response_object_from_error() {
529 let id = json_rpc::Id::Null;
530 let res = json_rpc::ResponseObject::from_error(
531 id,
532 json_rpc::Error {
533 code: crate::ErrorCodes::ParseError,
534 message: "invalid format".into(),
535 data: None,
536 },
537 );
538
539 let ser = serde_json::to_string(&res).unwrap();
540 assert_eq!(
541 r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"invalid format"},"id":null}"#,
542 &ser
543 );
544
545 let id = json_rpc::Id::String("foo-req".into());
546 let res = json_rpc::ResponseObject::from_error(
547 id,
548 json_rpc::Error {
549 code: crate::ErrorCodes::Custom(-32803),
550 message: "failed to foo the bar".into(),
551 data: Some(json!("hi")),
552 },
553 );
554
555 let ser = serde_json::to_string(&res).unwrap();
556 assert_eq!(
557 r#"{"jsonrpc":"2.0","error":{"code":-32803,"message":"failed to foo the bar","data":"hi"},"id":"foo-req"}"#,
558 &ser
559 );
560
561 let id = json_rpc::Id::String("foo-req".into());
562 let res = json_rpc::ResponseObject::from_error(
563 id,
564 json_rpc::Error {
565 code: crate::ErrorCodes::Custom(crate::LspErrorCodes::ContentModified.into()),
566 message: "failed to foo the bar".into(),
567 data: Some(json!("hi")),
568 },
569 );
570
571 let ser = serde_json::to_string(&res).unwrap();
572 assert_eq!(
573 r#"{"jsonrpc":"2.0","error":{"code":-32801,"message":"failed to foo the bar","data":"hi"},"id":"foo-req"}"#,
574 &ser
575 );
576 }
577
578 #[test]
579 fn structures_new_constructor() {
580 assert_eq!(
581 Position::new(1, 2),
582 Position {
583 line: 1,
584 character: 2
585 }
586 );
587 assert_eq!(
588 Range::new(Position::new(0, 0), Position::new(0, 99)),
589 Range {
590 start: Position::default(),
591 end: Position {
592 line: 0,
593 character: 99
594 }
595 }
596 );
597
598 assert_eq!(
599 Location::new(Uri("foo".into()), Range::default()),
600 Location {
601 uri: Uri("foo".into()),
602 range: Range::default()
603 }
604 );
605
606 assert_eq!(
608 Diagnostic::new(
609 Range::default(),
610 Some(DiagnosticSeverity::Warning),
611 None,
612 None,
613 None,
614 "bad".into(),
615 None,
616 None,
617 None
618 ),
619 Diagnostic {
620 range: Range::default(),
621 message: "bad".into(),
622 severity: Some(DiagnosticSeverity::Warning),
623 ..Default::default()
624 }
625 );
626 }
627
628 #[test]
629 fn custom_request_object_methods() {
630 struct ParentModule;
631 impl Request for ParentModule {
632 type Params = ();
633 type Result = Option<DefinitionResponse>;
634 const METHOD: LspRequestMethod<'_> =
635 LspRequestMethod::Custom("experimental/parentModule");
636 const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer;
637 }
638
639 let req =
640 json_rpc::RequestObject::from_request::<ParentModule>(json_rpc::Id::Number(123), ());
641 assert_eq!(
642 r#"{"jsonrpc":"2.0","id":123,"method":"experimental/parentModule"}"#,
643 serde_json::to_string(&req).unwrap()
644 );
645
646 struct ServerStatusNotification;
647 impl Notification for ServerStatusNotification {
648 type Params = ();
649 const METHOD: LspNotificationMethod<'_> =
650 LspNotificationMethod::new("experimental/serverStatus");
651 const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer;
652 }
653
654 let noti = json_rpc::RequestObject::from_notification::<ServerStatusNotification>(());
655 assert_eq!(
656 r#"{"jsonrpc":"2.0","method":"experimental/serverStatus"}"#,
657 serde_json::to_string(¬i).unwrap()
658 );
659
660 let method: &'static str = <ParentModule as Request>::METHOD.as_str();
662 assert_eq!(method, "experimental/parentModule");
663 let method = LspRequestMethod::new("asdf");
664 let method_str: &'static str = method.as_str();
665 assert_eq!(method_str, "asdf");
666 let method = LspRequestMethod::Custom("asdf");
667 let method_str: &'static str = method.as_str();
668 assert_eq!(method_str, "asdf");
669 let owned = String::from("workspace/didCreateFiles");
670 let method: LspNotificationMethod<'_> = owned.as_str().into();
671 assert_eq!(method, LspNotificationMethod::WorkspaceDidCreateFiles);
672 let owned = String::from("foo");
673 let method: LspNotificationMethod<'_> = owned.as_str().into();
674 assert_eq!(method, LspNotificationMethod::new("foo"));
675 let method1 = LspRequestMethod::TextDocumentCompletion;
677 let method2 = method1;
678 assert_eq!(method1, method2);
679 #[allow(clippy::match_same_arms)]
681 match method {
682 LspNotificationMethod::TextDocumentWillSave => {}
683 LspNotificationMethod::Custom("foo") => {}
684 LspNotificationMethod::Custom(_) => {}
685 _ => {}
686 }
687 }
688
689 #[test]
690 fn request_with_partial_results() {
691 fn foo<R: RequestWithPartialResults>(
692 _params: R::Params,
693 _partial_result: R::PartialResult,
694 ) {
695 }
697
698 foo::<DocumentSymbolRequest>(
699 DocumentSymbolParams {
700 text_document: TextDocumentIdentifier { uri: "".into() },
701 work_done_progress_params: WorkDoneProgressParams {
702 work_done_token: None,
703 },
704 partial_result_params: PartialResultParams {
705 partial_result_token: None,
706 },
707 },
708 DocumentSymbolPartialResponse::SymbolInformationList(vec![SymbolInformation {
709 deprecated: None,
710 location: Location {
711 uri: "".into(),
712 range: Range::default(),
713 },
714 base_symbol_information: BaseSymbolInformation {
715 name: String::new(),
716 kind: SymbolKind::File,
717 tags: None,
718 container_name: None,
719 },
720 }]),
721 );
722
723 let partial_result = DocumentSymbolPartialResponse::DocumentSymbolList(Vec::new());
724 let _ = match partial_result {
725 DocumentSymbolPartialResponse::SymbolInformationList(_) => 1,
726 DocumentSymbolPartialResponse::DocumentSymbolList(_) => 2,
727 };
729 }
730
731 #[test]
732 #[allow(clippy::similar_names)]
733 fn semantic_tokens() {
734 let ste = SemanticTokensEdit {
735 start: 0,
736 delete_count: 1,
737 data: None,
738 };
739 let ste_ser = r#"{"start":0,"deleteCount":1}"#;
740 assert_eq!(serde_json::to_string(&ste).unwrap(), ste_ser);
741 assert_eq!(ste, serde_json::from_str(ste_ser).unwrap());
742
743 let ste = SemanticTokensEdit {
744 start: 0,
745 delete_count: 1,
746 data: None,
747 };
748 let ste_ser_fake = r#"{"start":0,"deleteCount":1,"data":null}"#;
749 assert_eq!(serde_json::to_string(&ste).unwrap(), ste_ser);
750 assert_eq!(ste, serde_json::from_str(ste_ser_fake).unwrap());
752
753 let ste = SemanticTokensEdit {
754 start: 0,
755 delete_count: 1,
756 data: Some(vec![
757 SemanticToken {
758 delta_line: 2,
759 delta_start: 5,
760 length: 3,
761 token_type: 0,
762 token_modifiers_bitset: 3,
763 },
764 SemanticToken {
765 delta_line: 0,
766 delta_start: 5,
767 length: 4,
768 token_type: 1,
769 token_modifiers_bitset: 0,
770 },
771 ]),
772 };
773 let ste_ser = r#"{"start":0,"deleteCount":1,"data":[2,5,3,0,3,0,5,4,1,0]}"#;
774 assert_eq!(serde_json::to_string(&ste).unwrap(), ste_ser);
775 assert_eq!(ste, serde_json::from_str(ste_ser).unwrap());
776
777 let ste = SemanticTokensEdit {
778 start: 0,
779 delete_count: 1,
780 data: Some(Vec::new()),
781 };
782 let ste_ser = r#"{"start":0,"deleteCount":1,"data":[]}"#;
783 assert_eq!(serde_json::to_string(&ste).unwrap(), ste_ser);
784 assert_eq!(ste, serde_json::from_str(ste_ser).unwrap());
785
786 let st = SemanticTokens {
787 result_id: None,
788 data: Vec::default(),
789 };
790 let st_ser = r#"{"data":[]}"#;
791 assert_eq!(serde_json::to_string(&st).unwrap(), st_ser);
792 assert_eq!(st, serde_json::from_str(st_ser).unwrap());
793
794 let st = SemanticTokens {
795 result_id: None,
796 data: vec![
797 SemanticToken {
798 delta_line: 2,
799 delta_start: 5,
800 length: 3,
801 token_type: 0,
802 token_modifiers_bitset: 3,
803 },
804 SemanticToken {
805 delta_line: 0,
806 delta_start: 5,
807 length: 4,
808 token_type: 1,
809 token_modifiers_bitset: 0,
810 },
811 ],
812 };
813 let st_ser = r#"{"data":[2,5,3,0,3,0,5,4,1,0]}"#;
814 assert_eq!(serde_json::to_string(&st).unwrap(), st_ser);
815 assert_eq!(st, serde_json::from_str(st_ser).unwrap());
816
817 let stpr = SemanticTokensPartialResult {
818 data: vec![
819 SemanticToken {
820 delta_line: 2,
821 delta_start: 5,
822 length: 3,
823 token_type: 0,
824 token_modifiers_bitset: 3,
825 },
826 SemanticToken {
827 delta_line: 0,
828 delta_start: 5,
829 length: 4,
830 token_type: 1,
831 token_modifiers_bitset: 0,
832 },
833 ],
834 };
835 let stpr_ser = r#"{"data":[2,5,3,0,3,0,5,4,1,0]}"#;
836 assert_eq!(serde_json::to_string(&stpr).unwrap(), stpr_ser);
837 assert_eq!(stpr, serde_json::from_str(stpr_ser).unwrap());
838
839 let stpr = SemanticTokensPartialResult {
840 data: Vec::default(),
841 };
842 let stpr_ser = r#"{"data":[]}"#;
843 assert_eq!(serde_json::to_string(&stpr).unwrap(), stpr_ser);
844 assert_eq!(stpr, serde_json::from_str(stpr_ser).unwrap());
845 }
846
847 #[test]
848 fn request_macro() {
849 let req = json_rpc::RequestObject::from_request::<lsp_request!("workspace/workspaceFolders")>(
850 json_rpc::Id::Number(123),
851 (),
852 );
853
854 assert_eq!(
855 r#"{"jsonrpc":"2.0","id":123,"method":"workspace/workspaceFolders"}"#,
856 serde_json::to_string(&req).unwrap()
857 );
858 }
859
860 #[test]
861 fn notification_macro() {
862 let req = json_rpc::RequestObject::from_notification::<lsp_notification!("exit")>(());
863
864 assert_eq!(
865 r#"{"jsonrpc":"2.0","method":"exit"}"#,
866 serde_json::to_string(&req).unwrap()
867 );
868 }
869
870 #[test]
871 fn tuple_serialization() {
872 let pil = ParameterInformationLabel::Tuple((1, 2));
873 assert_eq!("[1,2]", serde_json::to_string(&pil).unwrap());
874 assert_eq!(pil, serde_json::from_str("[1,2]").unwrap());
875 }
876}
877
878#[cfg(test)]
880#[cfg(all(feature = "url", not(feature = "fluent-uri")))]
881mod test {
882 use crate::*;
883
884 #[test]
885 fn url_feature() {
886 let url = url::Url::parse("file://tmp/foo.txt/").unwrap();
887 let tdi = TextDocumentIdentifier { uri: url };
888 let ser = r#"{"uri":"file://tmp/foo.txt/"}"#;
889
890 assert_eq!(ser, serde_json::to_string(&tdi).unwrap());
891 assert_eq!(tdi, serde_json::from_str(ser).unwrap());
892 }
893}
894
895#[cfg(test)]
897#[cfg(all(feature = "fluent-uri", not(feature = "url")))]
898mod test {
899 use crate::*;
900
901 #[test]
902 fn url_feature() {
903 let uri = fluent_uri::Uri::try_from("file://tmp/foo.txt/".to_string()).unwrap();
904 let tdi = TextDocumentIdentifier { uri };
905 let ser = r#"{"uri":"file://tmp/foo.txt/"}"#;
906
907 assert_eq!(ser, serde_json::to_string(&tdi).unwrap());
908 assert_eq!(tdi, serde_json::from_str(ser).unwrap());
909 }
910}