1use std::{collections::BTreeMap, sync::Arc};
8
9use derive_more::{Display, From};
10use schemars::{JsonSchema, Schema};
11use serde::{Deserialize, Serialize};
12use serde_with::{DefaultOnError, VecSkipError, serde_as, skip_serializing_none};
13
14use super::{Meta, SessionId};
15use crate::{IntoOption, SkipListener};
16
17pub(crate) const NES_START_METHOD_NAME: &str = "nes/start";
21pub(crate) const NES_SUGGEST_METHOD_NAME: &str = "nes/suggest";
23pub(crate) const NES_ACCEPT_METHOD_NAME: &str = "nes/accept";
25pub(crate) const NES_REJECT_METHOD_NAME: &str = "nes/reject";
27
28#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
34#[serde(transparent)]
35#[from(Arc<str>, String, &'static str)]
36#[non_exhaustive]
37pub struct NesSuggestionId(pub Arc<str>);
38
39impl NesSuggestionId {
40 #[must_use]
42 pub fn new(id: impl Into<Arc<str>>) -> Self {
43 Self(id.into())
44 }
45}
46pub(crate) const NES_CLOSE_METHOD_NAME: &str = "nes/close";
48pub(crate) const DOCUMENT_DID_OPEN_METHOD_NAME: &str = "document/didOpen";
50pub(crate) const DOCUMENT_DID_CHANGE_METHOD_NAME: &str = "document/didChange";
52pub(crate) const DOCUMENT_DID_CLOSE_METHOD_NAME: &str = "document/didClose";
54pub(crate) const DOCUMENT_DID_SAVE_METHOD_NAME: &str = "document/didSave";
56pub(crate) const DOCUMENT_DID_FOCUS_METHOD_NAME: &str = "document/didFocus";
58
59#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
65#[non_exhaustive]
66pub enum PositionEncodingKind {
67 #[serde(rename = "utf-16")]
69 Utf16,
70 #[serde(rename = "utf-32")]
72 Utf32,
73 #[serde(rename = "utf-8")]
75 Utf8,
76}
77
78#[serde_as]
82#[skip_serializing_none]
83#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
84#[serde(rename_all = "camelCase")]
85#[non_exhaustive]
86pub struct Position {
87 pub line: u32,
89 pub character: u32,
91 #[serde_as(deserialize_as = "DefaultOnError")]
97 #[schemars(extend("x-deserialize-default-on-error" = true))]
98 #[serde(default)]
99 #[serde(rename = "_meta")]
100 pub meta: Option<Meta>,
101}
102
103impl Position {
104 #[must_use]
106 pub fn new(line: u32, character: u32) -> Self {
107 Self {
108 line,
109 character,
110 meta: None,
111 }
112 }
113
114 #[must_use]
120 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
121 self.meta = meta.into_option();
122 self
123 }
124}
125
126#[serde_as]
128#[skip_serializing_none]
129#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
130#[serde(rename_all = "camelCase")]
131#[non_exhaustive]
132pub struct Range {
133 pub start: Position,
135 pub end: Position,
137 #[serde_as(deserialize_as = "DefaultOnError")]
143 #[schemars(extend("x-deserialize-default-on-error" = true))]
144 #[serde(default)]
145 #[serde(rename = "_meta")]
146 pub meta: Option<Meta>,
147}
148
149impl Range {
150 #[must_use]
152 pub fn new(start: Position, end: Position) -> Self {
153 Self {
154 start,
155 end,
156 meta: None,
157 }
158 }
159
160 #[must_use]
166 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
167 self.meta = meta.into_option();
168 self
169 }
170}
171
172#[serde_as]
179#[skip_serializing_none]
180#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
181#[serde(rename_all = "camelCase")]
182#[non_exhaustive]
183pub struct NesCapabilities {
184 #[serde_as(deserialize_as = "DefaultOnError")]
186 #[schemars(extend("x-deserialize-default-on-error" = true))]
187 #[serde(default)]
188 pub events: Option<NesEventCapabilities>,
189 #[serde_as(deserialize_as = "DefaultOnError")]
191 #[schemars(extend("x-deserialize-default-on-error" = true))]
192 #[serde(default)]
193 pub context: Option<NesContextCapabilities>,
194 #[serde_as(deserialize_as = "DefaultOnError")]
200 #[schemars(extend("x-deserialize-default-on-error" = true))]
201 #[serde(default)]
202 #[serde(rename = "_meta")]
203 pub meta: Option<Meta>,
204}
205
206impl NesCapabilities {
207 #[must_use]
209 pub fn new() -> Self {
210 Self::default()
211 }
212
213 #[must_use]
215 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
216 self.events = events.into_option();
217 self
218 }
219
220 #[must_use]
222 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
223 self.context = context.into_option();
224 self
225 }
226
227 #[must_use]
233 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
234 self.meta = meta.into_option();
235 self
236 }
237}
238
239#[serde_as]
241#[skip_serializing_none]
242#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
243#[serde(rename_all = "camelCase")]
244#[non_exhaustive]
245pub struct NesEventCapabilities {
246 #[serde_as(deserialize_as = "DefaultOnError")]
248 #[schemars(extend("x-deserialize-default-on-error" = true))]
249 #[serde(default)]
250 pub document: Option<NesDocumentEventCapabilities>,
251 #[serde_as(deserialize_as = "DefaultOnError")]
257 #[schemars(extend("x-deserialize-default-on-error" = true))]
258 #[serde(default)]
259 #[serde(rename = "_meta")]
260 pub meta: Option<Meta>,
261}
262
263impl NesEventCapabilities {
264 #[must_use]
266 pub fn new() -> Self {
267 Self::default()
268 }
269
270 #[must_use]
272 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
273 self.document = document.into_option();
274 self
275 }
276
277 #[must_use]
283 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
284 self.meta = meta.into_option();
285 self
286 }
287}
288
289#[serde_as]
291#[skip_serializing_none]
292#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
293#[serde(rename_all = "camelCase")]
294#[non_exhaustive]
295pub struct NesDocumentEventCapabilities {
296 #[serde_as(deserialize_as = "DefaultOnError")]
298 #[schemars(extend("x-deserialize-default-on-error" = true))]
299 #[serde(default)]
300 pub did_open: Option<NesDocumentDidOpenCapabilities>,
301 #[serde_as(deserialize_as = "DefaultOnError")]
303 #[schemars(extend("x-deserialize-default-on-error" = true))]
304 #[serde(default)]
305 pub did_change: Option<NesDocumentDidChangeCapabilities>,
306 #[serde_as(deserialize_as = "DefaultOnError")]
308 #[schemars(extend("x-deserialize-default-on-error" = true))]
309 #[serde(default)]
310 pub did_close: Option<NesDocumentDidCloseCapabilities>,
311 #[serde_as(deserialize_as = "DefaultOnError")]
313 #[schemars(extend("x-deserialize-default-on-error" = true))]
314 #[serde(default)]
315 pub did_save: Option<NesDocumentDidSaveCapabilities>,
316 #[serde_as(deserialize_as = "DefaultOnError")]
318 #[schemars(extend("x-deserialize-default-on-error" = true))]
319 #[serde(default)]
320 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
321 #[serde_as(deserialize_as = "DefaultOnError")]
327 #[schemars(extend("x-deserialize-default-on-error" = true))]
328 #[serde(default)]
329 #[serde(rename = "_meta")]
330 pub meta: Option<Meta>,
331}
332
333impl NesDocumentEventCapabilities {
334 #[must_use]
336 pub fn new() -> Self {
337 Self::default()
338 }
339
340 #[must_use]
342 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
343 self.did_open = did_open.into_option();
344 self
345 }
346
347 #[must_use]
349 pub fn did_change(
350 mut self,
351 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
352 ) -> Self {
353 self.did_change = did_change.into_option();
354 self
355 }
356
357 #[must_use]
359 pub fn did_close(
360 mut self,
361 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
362 ) -> Self {
363 self.did_close = did_close.into_option();
364 self
365 }
366
367 #[must_use]
369 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
370 self.did_save = did_save.into_option();
371 self
372 }
373
374 #[must_use]
376 pub fn did_focus(
377 mut self,
378 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
379 ) -> Self {
380 self.did_focus = did_focus.into_option();
381 self
382 }
383
384 #[must_use]
390 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
391 self.meta = meta.into_option();
392 self
393 }
394}
395
396#[serde_as]
398#[skip_serializing_none]
399#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
400#[serde(rename_all = "camelCase")]
401#[non_exhaustive]
402pub struct NesDocumentDidOpenCapabilities {
403 #[serde_as(deserialize_as = "DefaultOnError")]
409 #[schemars(extend("x-deserialize-default-on-error" = true))]
410 #[serde(default)]
411 #[serde(rename = "_meta")]
412 pub meta: Option<Meta>,
413}
414
415impl NesDocumentDidOpenCapabilities {
416 #[must_use]
418 pub fn new() -> Self {
419 Self::default()
420 }
421}
422
423#[serde_as]
425#[skip_serializing_none]
426#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
427#[serde(rename_all = "camelCase")]
428#[non_exhaustive]
429pub struct NesDocumentDidChangeCapabilities {
430 pub sync_kind: TextDocumentSyncKind,
432 #[serde_as(deserialize_as = "DefaultOnError")]
438 #[schemars(extend("x-deserialize-default-on-error" = true))]
439 #[serde(default)]
440 #[serde(rename = "_meta")]
441 pub meta: Option<Meta>,
442}
443
444impl NesDocumentDidChangeCapabilities {
445 #[must_use]
447 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
448 Self {
449 sync_kind,
450 meta: None,
451 }
452 }
453
454 #[must_use]
460 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
461 self.meta = meta.into_option();
462 self
463 }
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
468#[non_exhaustive]
469pub enum TextDocumentSyncKind {
470 #[serde(rename = "full")]
472 Full,
473 #[serde(rename = "incremental")]
475 Incremental,
476}
477
478#[serde_as]
480#[skip_serializing_none]
481#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
482#[serde(rename_all = "camelCase")]
483#[non_exhaustive]
484pub struct NesDocumentDidCloseCapabilities {
485 #[serde_as(deserialize_as = "DefaultOnError")]
491 #[schemars(extend("x-deserialize-default-on-error" = true))]
492 #[serde(default)]
493 #[serde(rename = "_meta")]
494 pub meta: Option<Meta>,
495}
496
497impl NesDocumentDidCloseCapabilities {
498 #[must_use]
500 pub fn new() -> Self {
501 Self::default()
502 }
503}
504
505#[serde_as]
507#[skip_serializing_none]
508#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
509#[serde(rename_all = "camelCase")]
510#[non_exhaustive]
511pub struct NesDocumentDidSaveCapabilities {
512 #[serde_as(deserialize_as = "DefaultOnError")]
518 #[schemars(extend("x-deserialize-default-on-error" = true))]
519 #[serde(default)]
520 #[serde(rename = "_meta")]
521 pub meta: Option<Meta>,
522}
523
524impl NesDocumentDidSaveCapabilities {
525 #[must_use]
527 pub fn new() -> Self {
528 Self::default()
529 }
530}
531
532#[serde_as]
534#[skip_serializing_none]
535#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
536#[serde(rename_all = "camelCase")]
537#[non_exhaustive]
538pub struct NesDocumentDidFocusCapabilities {
539 #[serde_as(deserialize_as = "DefaultOnError")]
545 #[schemars(extend("x-deserialize-default-on-error" = true))]
546 #[serde(default)]
547 #[serde(rename = "_meta")]
548 pub meta: Option<Meta>,
549}
550
551impl NesDocumentDidFocusCapabilities {
552 #[must_use]
554 pub fn new() -> Self {
555 Self::default()
556 }
557}
558
559#[serde_as]
561#[skip_serializing_none]
562#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
563#[serde(rename_all = "camelCase")]
564#[non_exhaustive]
565pub struct NesContextCapabilities {
566 #[serde_as(deserialize_as = "DefaultOnError")]
568 #[schemars(extend("x-deserialize-default-on-error" = true))]
569 #[serde(default)]
570 pub recent_files: Option<NesRecentFilesCapabilities>,
571 #[serde_as(deserialize_as = "DefaultOnError")]
573 #[schemars(extend("x-deserialize-default-on-error" = true))]
574 #[serde(default)]
575 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
576 #[serde_as(deserialize_as = "DefaultOnError")]
578 #[schemars(extend("x-deserialize-default-on-error" = true))]
579 #[serde(default)]
580 pub edit_history: Option<NesEditHistoryCapabilities>,
581 #[serde_as(deserialize_as = "DefaultOnError")]
583 #[schemars(extend("x-deserialize-default-on-error" = true))]
584 #[serde(default)]
585 pub user_actions: Option<NesUserActionsCapabilities>,
586 #[serde_as(deserialize_as = "DefaultOnError")]
588 #[schemars(extend("x-deserialize-default-on-error" = true))]
589 #[serde(default)]
590 pub open_files: Option<NesOpenFilesCapabilities>,
591 #[serde_as(deserialize_as = "DefaultOnError")]
593 #[schemars(extend("x-deserialize-default-on-error" = true))]
594 #[serde(default)]
595 pub diagnostics: Option<NesDiagnosticsCapabilities>,
596 #[serde_as(deserialize_as = "DefaultOnError")]
602 #[schemars(extend("x-deserialize-default-on-error" = true))]
603 #[serde(default)]
604 #[serde(rename = "_meta")]
605 pub meta: Option<Meta>,
606}
607
608impl NesContextCapabilities {
609 #[must_use]
611 pub fn new() -> Self {
612 Self::default()
613 }
614
615 #[must_use]
617 pub fn recent_files(
618 mut self,
619 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
620 ) -> Self {
621 self.recent_files = recent_files.into_option();
622 self
623 }
624
625 #[must_use]
627 pub fn related_snippets(
628 mut self,
629 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
630 ) -> Self {
631 self.related_snippets = related_snippets.into_option();
632 self
633 }
634
635 #[must_use]
637 pub fn edit_history(
638 mut self,
639 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
640 ) -> Self {
641 self.edit_history = edit_history.into_option();
642 self
643 }
644
645 #[must_use]
647 pub fn user_actions(
648 mut self,
649 user_actions: impl IntoOption<NesUserActionsCapabilities>,
650 ) -> Self {
651 self.user_actions = user_actions.into_option();
652 self
653 }
654
655 #[must_use]
657 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
658 self.open_files = open_files.into_option();
659 self
660 }
661
662 #[must_use]
664 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
665 self.diagnostics = diagnostics.into_option();
666 self
667 }
668
669 #[must_use]
675 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
676 self.meta = meta.into_option();
677 self
678 }
679}
680
681#[serde_as]
683#[skip_serializing_none]
684#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
685#[serde(rename_all = "camelCase")]
686#[non_exhaustive]
687pub struct NesRecentFilesCapabilities {
688 #[serde_as(deserialize_as = "DefaultOnError")]
690 #[schemars(extend("x-deserialize-default-on-error" = true))]
691 #[serde(default)]
692 pub max_count: Option<u32>,
693 #[serde_as(deserialize_as = "DefaultOnError")]
699 #[schemars(extend("x-deserialize-default-on-error" = true))]
700 #[serde(default)]
701 #[serde(rename = "_meta")]
702 pub meta: Option<Meta>,
703}
704
705impl NesRecentFilesCapabilities {
706 #[must_use]
708 pub fn new() -> Self {
709 Self::default()
710 }
711}
712
713#[serde_as]
715#[skip_serializing_none]
716#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
717#[serde(rename_all = "camelCase")]
718#[non_exhaustive]
719pub struct NesRelatedSnippetsCapabilities {
720 #[serde_as(deserialize_as = "DefaultOnError")]
726 #[schemars(extend("x-deserialize-default-on-error" = true))]
727 #[serde(default)]
728 #[serde(rename = "_meta")]
729 pub meta: Option<Meta>,
730}
731
732impl NesRelatedSnippetsCapabilities {
733 #[must_use]
735 pub fn new() -> Self {
736 Self::default()
737 }
738}
739
740#[serde_as]
742#[skip_serializing_none]
743#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
744#[serde(rename_all = "camelCase")]
745#[non_exhaustive]
746pub struct NesEditHistoryCapabilities {
747 #[serde_as(deserialize_as = "DefaultOnError")]
749 #[schemars(extend("x-deserialize-default-on-error" = true))]
750 #[serde(default)]
751 pub max_count: Option<u32>,
752 #[serde_as(deserialize_as = "DefaultOnError")]
758 #[schemars(extend("x-deserialize-default-on-error" = true))]
759 #[serde(default)]
760 #[serde(rename = "_meta")]
761 pub meta: Option<Meta>,
762}
763
764impl NesEditHistoryCapabilities {
765 #[must_use]
767 pub fn new() -> Self {
768 Self::default()
769 }
770}
771
772#[serde_as]
774#[skip_serializing_none]
775#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
776#[serde(rename_all = "camelCase")]
777#[non_exhaustive]
778pub struct NesUserActionsCapabilities {
779 #[serde_as(deserialize_as = "DefaultOnError")]
781 #[schemars(extend("x-deserialize-default-on-error" = true))]
782 #[serde(default)]
783 pub max_count: Option<u32>,
784 #[serde_as(deserialize_as = "DefaultOnError")]
790 #[schemars(extend("x-deserialize-default-on-error" = true))]
791 #[serde(default)]
792 #[serde(rename = "_meta")]
793 pub meta: Option<Meta>,
794}
795
796impl NesUserActionsCapabilities {
797 #[must_use]
799 pub fn new() -> Self {
800 Self::default()
801 }
802}
803
804#[serde_as]
806#[skip_serializing_none]
807#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
808#[serde(rename_all = "camelCase")]
809#[non_exhaustive]
810pub struct NesOpenFilesCapabilities {
811 #[serde_as(deserialize_as = "DefaultOnError")]
817 #[schemars(extend("x-deserialize-default-on-error" = true))]
818 #[serde(default)]
819 #[serde(rename = "_meta")]
820 pub meta: Option<Meta>,
821}
822
823impl NesOpenFilesCapabilities {
824 #[must_use]
826 pub fn new() -> Self {
827 Self::default()
828 }
829}
830
831#[serde_as]
833#[skip_serializing_none]
834#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
835#[serde(rename_all = "camelCase")]
836#[non_exhaustive]
837pub struct NesDiagnosticsCapabilities {
838 #[serde_as(deserialize_as = "DefaultOnError")]
844 #[schemars(extend("x-deserialize-default-on-error" = true))]
845 #[serde(default)]
846 #[serde(rename = "_meta")]
847 pub meta: Option<Meta>,
848}
849
850impl NesDiagnosticsCapabilities {
851 #[must_use]
853 pub fn new() -> Self {
854 Self::default()
855 }
856}
857
858#[serde_as]
862#[skip_serializing_none]
863#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
864#[serde(rename_all = "camelCase")]
865#[non_exhaustive]
866pub struct ClientNesCapabilities {
867 #[serde_as(deserialize_as = "DefaultOnError")]
869 #[schemars(extend("x-deserialize-default-on-error" = true))]
870 #[serde(default)]
871 pub jump: Option<NesJumpCapabilities>,
872 #[serde_as(deserialize_as = "DefaultOnError")]
874 #[schemars(extend("x-deserialize-default-on-error" = true))]
875 #[serde(default)]
876 pub rename: Option<NesRenameCapabilities>,
877 #[serde_as(deserialize_as = "DefaultOnError")]
879 #[schemars(extend("x-deserialize-default-on-error" = true))]
880 #[serde(default)]
881 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
882 #[serde_as(deserialize_as = "DefaultOnError")]
888 #[schemars(extend("x-deserialize-default-on-error" = true))]
889 #[serde(default)]
890 #[serde(rename = "_meta")]
891 pub meta: Option<Meta>,
892}
893
894impl ClientNesCapabilities {
895 #[must_use]
897 pub fn new() -> Self {
898 Self::default()
899 }
900
901 #[must_use]
903 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
904 self.jump = jump.into_option();
905 self
906 }
907
908 #[must_use]
910 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
911 self.rename = rename.into_option();
912 self
913 }
914
915 #[must_use]
917 pub fn search_and_replace(
918 mut self,
919 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
920 ) -> Self {
921 self.search_and_replace = search_and_replace.into_option();
922 self
923 }
924
925 #[must_use]
931 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
932 self.meta = meta.into_option();
933 self
934 }
935}
936
937#[serde_as]
939#[skip_serializing_none]
940#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
941#[serde(rename_all = "camelCase")]
942#[non_exhaustive]
943pub struct NesJumpCapabilities {
944 #[serde_as(deserialize_as = "DefaultOnError")]
950 #[schemars(extend("x-deserialize-default-on-error" = true))]
951 #[serde(default)]
952 #[serde(rename = "_meta")]
953 pub meta: Option<Meta>,
954}
955
956impl NesJumpCapabilities {
957 #[must_use]
959 pub fn new() -> Self {
960 Self::default()
961 }
962}
963
964#[serde_as]
966#[skip_serializing_none]
967#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
968#[serde(rename_all = "camelCase")]
969#[non_exhaustive]
970pub struct NesRenameCapabilities {
971 #[serde_as(deserialize_as = "DefaultOnError")]
977 #[schemars(extend("x-deserialize-default-on-error" = true))]
978 #[serde(default)]
979 #[serde(rename = "_meta")]
980 pub meta: Option<Meta>,
981}
982
983impl NesRenameCapabilities {
984 #[must_use]
986 pub fn new() -> Self {
987 Self::default()
988 }
989}
990
991#[serde_as]
993#[skip_serializing_none]
994#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
995#[serde(rename_all = "camelCase")]
996#[non_exhaustive]
997pub struct NesSearchAndReplaceCapabilities {
998 #[serde_as(deserialize_as = "DefaultOnError")]
1004 #[schemars(extend("x-deserialize-default-on-error" = true))]
1005 #[serde(default)]
1006 #[serde(rename = "_meta")]
1007 pub meta: Option<Meta>,
1008}
1009
1010impl NesSearchAndReplaceCapabilities {
1011 #[must_use]
1013 pub fn new() -> Self {
1014 Self::default()
1015 }
1016}
1017
1018#[serde_as]
1022#[skip_serializing_none]
1023#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1024#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME))]
1025#[serde(rename_all = "camelCase")]
1026#[non_exhaustive]
1027pub struct DidOpenDocumentNotification {
1028 pub session_id: SessionId,
1030 #[schemars(url)]
1032 pub uri: String,
1033 pub language_id: String,
1035 pub version: i64,
1037 pub text: String,
1039 #[serde_as(deserialize_as = "DefaultOnError")]
1045 #[schemars(extend("x-deserialize-default-on-error" = true))]
1046 #[serde(default)]
1047 #[serde(rename = "_meta")]
1048 pub meta: Option<Meta>,
1049}
1050
1051impl DidOpenDocumentNotification {
1052 #[must_use]
1054 pub fn new(
1055 session_id: impl Into<SessionId>,
1056 uri: impl Into<String>,
1057 language_id: impl Into<String>,
1058 version: i64,
1059 text: impl Into<String>,
1060 ) -> Self {
1061 Self {
1062 session_id: session_id.into(),
1063 uri: uri.into(),
1064 language_id: language_id.into(),
1065 version,
1066 text: text.into(),
1067 meta: None,
1068 }
1069 }
1070
1071 #[must_use]
1077 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1078 self.meta = meta.into_option();
1079 self
1080 }
1081}
1082
1083#[serde_as]
1085#[skip_serializing_none]
1086#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1087#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME))]
1088#[serde(rename_all = "camelCase")]
1089#[non_exhaustive]
1090pub struct DidChangeDocumentNotification {
1091 pub session_id: SessionId,
1093 #[schemars(url)]
1095 pub uri: String,
1096 pub version: i64,
1098 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
1100 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1101 pub content_changes: Vec<TextDocumentContentChangeEvent>,
1102 #[serde_as(deserialize_as = "DefaultOnError")]
1108 #[schemars(extend("x-deserialize-default-on-error" = true))]
1109 #[serde(default)]
1110 #[serde(rename = "_meta")]
1111 pub meta: Option<Meta>,
1112}
1113
1114impl DidChangeDocumentNotification {
1115 #[must_use]
1117 pub fn new(
1118 session_id: impl Into<SessionId>,
1119 uri: impl Into<String>,
1120 version: i64,
1121 content_changes: Vec<TextDocumentContentChangeEvent>,
1122 ) -> Self {
1123 Self {
1124 session_id: session_id.into(),
1125 uri: uri.into(),
1126 version,
1127 content_changes,
1128 meta: None,
1129 }
1130 }
1131
1132 #[must_use]
1138 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1139 self.meta = meta.into_option();
1140 self
1141 }
1142}
1143
1144#[serde_as]
1149#[skip_serializing_none]
1150#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1151#[serde(rename_all = "camelCase")]
1152#[non_exhaustive]
1153pub struct TextDocumentContentChangeEvent {
1154 #[serde(default)]
1156 pub range: Option<Range>,
1157 pub text: String,
1159 #[serde_as(deserialize_as = "DefaultOnError")]
1165 #[schemars(extend("x-deserialize-default-on-error" = true))]
1166 #[serde(default)]
1167 #[serde(rename = "_meta")]
1168 pub meta: Option<Meta>,
1169}
1170
1171impl TextDocumentContentChangeEvent {
1172 #[must_use]
1174 pub fn full(text: impl Into<String>) -> Self {
1175 Self {
1176 range: None,
1177 text: text.into(),
1178 meta: None,
1179 }
1180 }
1181
1182 #[must_use]
1184 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
1185 Self {
1186 range: Some(range),
1187 text: text.into(),
1188 meta: None,
1189 }
1190 }
1191
1192 #[must_use]
1198 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1199 self.meta = meta.into_option();
1200 self
1201 }
1202}
1203
1204#[serde_as]
1206#[skip_serializing_none]
1207#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1208#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME))]
1209#[serde(rename_all = "camelCase")]
1210#[non_exhaustive]
1211pub struct DidCloseDocumentNotification {
1212 pub session_id: SessionId,
1214 #[schemars(url)]
1216 pub uri: String,
1217 #[serde_as(deserialize_as = "DefaultOnError")]
1223 #[schemars(extend("x-deserialize-default-on-error" = true))]
1224 #[serde(default)]
1225 #[serde(rename = "_meta")]
1226 pub meta: Option<Meta>,
1227}
1228
1229impl DidCloseDocumentNotification {
1230 #[must_use]
1232 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1233 Self {
1234 session_id: session_id.into(),
1235 uri: uri.into(),
1236 meta: None,
1237 }
1238 }
1239
1240 #[must_use]
1246 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1247 self.meta = meta.into_option();
1248 self
1249 }
1250}
1251
1252#[serde_as]
1254#[skip_serializing_none]
1255#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1256#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_SAVE_METHOD_NAME))]
1257#[serde(rename_all = "camelCase")]
1258#[non_exhaustive]
1259pub struct DidSaveDocumentNotification {
1260 pub session_id: SessionId,
1262 #[schemars(url)]
1264 pub uri: String,
1265 #[serde_as(deserialize_as = "DefaultOnError")]
1271 #[schemars(extend("x-deserialize-default-on-error" = true))]
1272 #[serde(default)]
1273 #[serde(rename = "_meta")]
1274 pub meta: Option<Meta>,
1275}
1276
1277impl DidSaveDocumentNotification {
1278 #[must_use]
1280 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1281 Self {
1282 session_id: session_id.into(),
1283 uri: uri.into(),
1284 meta: None,
1285 }
1286 }
1287
1288 #[must_use]
1294 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1295 self.meta = meta.into_option();
1296 self
1297 }
1298}
1299
1300#[serde_as]
1302#[skip_serializing_none]
1303#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1304#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME))]
1305#[serde(rename_all = "camelCase")]
1306#[non_exhaustive]
1307pub struct DidFocusDocumentNotification {
1308 pub session_id: SessionId,
1310 #[schemars(url)]
1312 pub uri: String,
1313 pub version: i64,
1315 pub position: Position,
1317 pub visible_range: Range,
1319 #[serde_as(deserialize_as = "DefaultOnError")]
1325 #[schemars(extend("x-deserialize-default-on-error" = true))]
1326 #[serde(default)]
1327 #[serde(rename = "_meta")]
1328 pub meta: Option<Meta>,
1329}
1330
1331impl DidFocusDocumentNotification {
1332 #[must_use]
1334 pub fn new(
1335 session_id: impl Into<SessionId>,
1336 uri: impl Into<String>,
1337 version: i64,
1338 position: Position,
1339 visible_range: Range,
1340 ) -> Self {
1341 Self {
1342 session_id: session_id.into(),
1343 uri: uri.into(),
1344 version,
1345 position,
1346 visible_range,
1347 meta: None,
1348 }
1349 }
1350
1351 #[must_use]
1357 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1358 self.meta = meta.into_option();
1359 self
1360 }
1361}
1362
1363#[serde_as]
1367#[skip_serializing_none]
1368#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1369#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1370#[serde(rename_all = "camelCase")]
1371#[non_exhaustive]
1372pub struct StartNesRequest {
1373 #[serde_as(deserialize_as = "DefaultOnError")]
1375 #[schemars(extend("x-deserialize-default-on-error" = true))]
1376 #[schemars(url)]
1377 #[serde(default)]
1378 pub workspace_uri: Option<String>,
1379 #[serde(default)]
1381 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1382 #[serde_as(deserialize_as = "DefaultOnError")]
1384 #[schemars(extend("x-deserialize-default-on-error" = true))]
1385 #[serde(default)]
1386 pub repository: Option<NesRepository>,
1387 #[serde_as(deserialize_as = "DefaultOnError")]
1393 #[schemars(extend("x-deserialize-default-on-error" = true))]
1394 #[serde(default)]
1395 #[serde(rename = "_meta")]
1396 pub meta: Option<Meta>,
1397}
1398
1399impl StartNesRequest {
1400 #[must_use]
1402 pub fn new() -> Self {
1403 Self {
1404 workspace_uri: None,
1405 workspace_folders: None,
1406 repository: None,
1407 meta: None,
1408 }
1409 }
1410
1411 #[must_use]
1413 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1414 self.workspace_uri = workspace_uri.into_option();
1415 self
1416 }
1417
1418 #[must_use]
1420 pub fn workspace_folders(
1421 mut self,
1422 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1423 ) -> Self {
1424 self.workspace_folders = workspace_folders.into_option();
1425 self
1426 }
1427
1428 #[must_use]
1430 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1431 self.repository = repository.into_option();
1432 self
1433 }
1434
1435 #[must_use]
1441 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1442 self.meta = meta.into_option();
1443 self
1444 }
1445}
1446
1447impl Default for StartNesRequest {
1448 fn default() -> Self {
1449 Self::new()
1450 }
1451}
1452
1453#[serde_as]
1455#[skip_serializing_none]
1456#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1457#[serde(rename_all = "camelCase")]
1458#[non_exhaustive]
1459pub struct WorkspaceFolder {
1460 #[schemars(url)]
1462 pub uri: String,
1463 pub name: String,
1465 #[serde_as(deserialize_as = "DefaultOnError")]
1471 #[schemars(extend("x-deserialize-default-on-error" = true))]
1472 #[serde(default)]
1473 #[serde(rename = "_meta")]
1474 pub meta: Option<Meta>,
1475}
1476
1477impl WorkspaceFolder {
1478 #[must_use]
1480 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1481 Self {
1482 uri: uri.into(),
1483 name: name.into(),
1484 meta: None,
1485 }
1486 }
1487
1488 #[must_use]
1494 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1495 self.meta = meta.into_option();
1496 self
1497 }
1498}
1499
1500#[serde_as]
1502#[skip_serializing_none]
1503#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1504#[serde(rename_all = "camelCase")]
1505#[non_exhaustive]
1506pub struct NesRepository {
1507 pub name: String,
1509 pub owner: String,
1511 pub remote_url: String,
1513 #[serde_as(deserialize_as = "DefaultOnError")]
1519 #[schemars(extend("x-deserialize-default-on-error" = true))]
1520 #[serde(default)]
1521 #[serde(rename = "_meta")]
1522 pub meta: Option<Meta>,
1523}
1524
1525impl NesRepository {
1526 #[must_use]
1528 pub fn new(
1529 name: impl Into<String>,
1530 owner: impl Into<String>,
1531 remote_url: impl Into<String>,
1532 ) -> Self {
1533 Self {
1534 name: name.into(),
1535 owner: owner.into(),
1536 remote_url: remote_url.into(),
1537 meta: None,
1538 }
1539 }
1540
1541 #[must_use]
1547 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1548 self.meta = meta.into_option();
1549 self
1550 }
1551}
1552
1553#[serde_as]
1555#[skip_serializing_none]
1556#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1557#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1558#[serde(rename_all = "camelCase")]
1559#[non_exhaustive]
1560pub struct StartNesResponse {
1561 pub session_id: SessionId,
1563 #[serde_as(deserialize_as = "DefaultOnError")]
1569 #[schemars(extend("x-deserialize-default-on-error" = true))]
1570 #[serde(default)]
1571 #[serde(rename = "_meta")]
1572 pub meta: Option<Meta>,
1573}
1574
1575impl StartNesResponse {
1576 #[must_use]
1578 pub fn new(session_id: impl Into<SessionId>) -> Self {
1579 Self {
1580 session_id: session_id.into(),
1581 meta: None,
1582 }
1583 }
1584
1585 #[must_use]
1591 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1592 self.meta = meta.into_option();
1593 self
1594 }
1595}
1596
1597#[serde_as]
1604#[skip_serializing_none]
1605#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1606#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1607#[serde(rename_all = "camelCase")]
1608#[non_exhaustive]
1609pub struct CloseNesRequest {
1610 pub session_id: SessionId,
1612 #[serde_as(deserialize_as = "DefaultOnError")]
1618 #[schemars(extend("x-deserialize-default-on-error" = true))]
1619 #[serde(default)]
1620 #[serde(rename = "_meta")]
1621 pub meta: Option<Meta>,
1622}
1623
1624impl CloseNesRequest {
1625 #[must_use]
1627 pub fn new(session_id: impl Into<SessionId>) -> Self {
1628 Self {
1629 session_id: session_id.into(),
1630 meta: None,
1631 }
1632 }
1633
1634 #[must_use]
1640 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1641 self.meta = meta.into_option();
1642 self
1643 }
1644}
1645
1646#[serde_as]
1648#[skip_serializing_none]
1649#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1650#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1651#[serde(rename_all = "camelCase")]
1652#[non_exhaustive]
1653pub struct CloseNesResponse {
1654 #[serde_as(deserialize_as = "DefaultOnError")]
1660 #[schemars(extend("x-deserialize-default-on-error" = true))]
1661 #[serde(default)]
1662 #[serde(rename = "_meta")]
1663 pub meta: Option<Meta>,
1664}
1665
1666impl CloseNesResponse {
1667 #[must_use]
1669 pub fn new() -> Self {
1670 Self::default()
1671 }
1672
1673 #[must_use]
1679 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1680 self.meta = meta.into_option();
1681 self
1682 }
1683}
1684
1685#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1689#[non_exhaustive]
1690pub enum NesTriggerKind {
1691 #[serde(rename = "automatic")]
1693 Automatic,
1694 #[serde(rename = "diagnostic")]
1696 Diagnostic,
1697 #[serde(rename = "manual")]
1699 Manual,
1700 #[serde(untagged)]
1706 Other(String),
1707}
1708
1709#[serde_as]
1711#[skip_serializing_none]
1712#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1713#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1714#[serde(rename_all = "camelCase")]
1715#[non_exhaustive]
1716pub struct SuggestNesRequest {
1717 pub session_id: SessionId,
1719 #[schemars(url)]
1721 pub uri: String,
1722 pub version: i64,
1724 pub position: Position,
1726 #[serde(default)]
1728 pub selection: Option<Range>,
1729 pub trigger_kind: NesTriggerKind,
1731 #[serde(default)]
1733 pub context: Option<NesSuggestContext>,
1734 #[serde_as(deserialize_as = "DefaultOnError")]
1740 #[schemars(extend("x-deserialize-default-on-error" = true))]
1741 #[serde(default)]
1742 #[serde(rename = "_meta")]
1743 pub meta: Option<Meta>,
1744}
1745
1746impl SuggestNesRequest {
1747 #[must_use]
1749 pub fn new(
1750 session_id: impl Into<SessionId>,
1751 uri: impl Into<String>,
1752 version: i64,
1753 position: Position,
1754 trigger_kind: NesTriggerKind,
1755 ) -> Self {
1756 Self {
1757 session_id: session_id.into(),
1758 uri: uri.into(),
1759 version,
1760 position,
1761 selection: None,
1762 trigger_kind,
1763 context: None,
1764 meta: None,
1765 }
1766 }
1767
1768 #[must_use]
1770 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1771 self.selection = selection.into_option();
1772 self
1773 }
1774
1775 #[must_use]
1777 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1778 self.context = context.into_option();
1779 self
1780 }
1781
1782 #[must_use]
1788 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1789 self.meta = meta.into_option();
1790 self
1791 }
1792}
1793
1794#[serde_as]
1796#[skip_serializing_none]
1797#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1798#[serde(rename_all = "camelCase")]
1799#[non_exhaustive]
1800pub struct NesSuggestContext {
1801 #[serde(default)]
1803 pub recent_files: Option<Vec<NesRecentFile>>,
1804 #[serde(default)]
1806 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1807 #[serde(default)]
1809 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1810 #[serde(default)]
1812 pub user_actions: Option<Vec<NesUserAction>>,
1813 #[serde(default)]
1815 pub open_files: Option<Vec<NesOpenFile>>,
1816 #[serde(default)]
1818 pub diagnostics: Option<Vec<NesDiagnostic>>,
1819 #[serde_as(deserialize_as = "DefaultOnError")]
1825 #[schemars(extend("x-deserialize-default-on-error" = true))]
1826 #[serde(default)]
1827 #[serde(rename = "_meta")]
1828 pub meta: Option<Meta>,
1829}
1830
1831impl NesSuggestContext {
1832 #[must_use]
1834 pub fn new() -> Self {
1835 Self::default()
1836 }
1837
1838 #[must_use]
1840 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1841 self.recent_files = recent_files.into_option();
1842 self
1843 }
1844
1845 #[must_use]
1847 pub fn related_snippets(
1848 mut self,
1849 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1850 ) -> Self {
1851 self.related_snippets = related_snippets.into_option();
1852 self
1853 }
1854
1855 #[must_use]
1857 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1858 self.edit_history = edit_history.into_option();
1859 self
1860 }
1861
1862 #[must_use]
1864 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1865 self.user_actions = user_actions.into_option();
1866 self
1867 }
1868
1869 #[must_use]
1871 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1872 self.open_files = open_files.into_option();
1873 self
1874 }
1875
1876 #[must_use]
1878 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1879 self.diagnostics = diagnostics.into_option();
1880 self
1881 }
1882
1883 #[must_use]
1889 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1890 self.meta = meta.into_option();
1891 self
1892 }
1893}
1894
1895#[serde_as]
1897#[skip_serializing_none]
1898#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1899#[serde(rename_all = "camelCase")]
1900#[non_exhaustive]
1901pub struct NesRecentFile {
1902 #[schemars(url)]
1904 pub uri: String,
1905 pub language_id: String,
1907 pub text: String,
1909 #[serde_as(deserialize_as = "DefaultOnError")]
1915 #[schemars(extend("x-deserialize-default-on-error" = true))]
1916 #[serde(default)]
1917 #[serde(rename = "_meta")]
1918 pub meta: Option<Meta>,
1919}
1920
1921impl NesRecentFile {
1922 #[must_use]
1924 pub fn new(
1925 uri: impl Into<String>,
1926 language_id: impl Into<String>,
1927 text: impl Into<String>,
1928 ) -> Self {
1929 Self {
1930 uri: uri.into(),
1931 language_id: language_id.into(),
1932 text: text.into(),
1933 meta: None,
1934 }
1935 }
1936
1937 #[must_use]
1943 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1944 self.meta = meta.into_option();
1945 self
1946 }
1947}
1948
1949#[serde_as]
1951#[skip_serializing_none]
1952#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1953#[serde(rename_all = "camelCase")]
1954#[non_exhaustive]
1955pub struct NesRelatedSnippet {
1956 #[schemars(url)]
1958 pub uri: String,
1959 pub excerpts: Vec<NesExcerpt>,
1961 #[serde_as(deserialize_as = "DefaultOnError")]
1967 #[schemars(extend("x-deserialize-default-on-error" = true))]
1968 #[serde(default)]
1969 #[serde(rename = "_meta")]
1970 pub meta: Option<Meta>,
1971}
1972
1973impl NesRelatedSnippet {
1974 #[must_use]
1976 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
1977 Self {
1978 uri: uri.into(),
1979 excerpts,
1980 meta: None,
1981 }
1982 }
1983
1984 #[must_use]
1990 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1991 self.meta = meta.into_option();
1992 self
1993 }
1994}
1995
1996#[serde_as]
1998#[skip_serializing_none]
1999#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2000#[serde(rename_all = "camelCase")]
2001#[non_exhaustive]
2002pub struct NesExcerpt {
2003 pub start_line: u32,
2005 pub end_line: u32,
2007 pub text: String,
2009 #[serde_as(deserialize_as = "DefaultOnError")]
2015 #[schemars(extend("x-deserialize-default-on-error" = true))]
2016 #[serde(default)]
2017 #[serde(rename = "_meta")]
2018 pub meta: Option<Meta>,
2019}
2020
2021impl NesExcerpt {
2022 #[must_use]
2024 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
2025 Self {
2026 start_line,
2027 end_line,
2028 text: text.into(),
2029 meta: None,
2030 }
2031 }
2032
2033 #[must_use]
2039 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2040 self.meta = meta.into_option();
2041 self
2042 }
2043}
2044
2045#[serde_as]
2047#[skip_serializing_none]
2048#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2049#[serde(rename_all = "camelCase")]
2050#[non_exhaustive]
2051pub struct NesEditHistoryEntry {
2052 #[schemars(url)]
2054 pub uri: String,
2055 pub diff: String,
2057 #[serde_as(deserialize_as = "DefaultOnError")]
2063 #[schemars(extend("x-deserialize-default-on-error" = true))]
2064 #[serde(default)]
2065 #[serde(rename = "_meta")]
2066 pub meta: Option<Meta>,
2067}
2068
2069impl NesEditHistoryEntry {
2070 #[must_use]
2072 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
2073 Self {
2074 uri: uri.into(),
2075 diff: diff.into(),
2076 meta: None,
2077 }
2078 }
2079
2080 #[must_use]
2086 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2087 self.meta = meta.into_option();
2088 self
2089 }
2090}
2091
2092#[serde_as]
2094#[skip_serializing_none]
2095#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2096#[serde(rename_all = "camelCase")]
2097#[non_exhaustive]
2098pub struct NesUserAction {
2099 pub action: String,
2101 #[schemars(url)]
2103 pub uri: String,
2104 pub position: Position,
2106 pub timestamp_ms: u64,
2108 #[serde_as(deserialize_as = "DefaultOnError")]
2114 #[schemars(extend("x-deserialize-default-on-error" = true))]
2115 #[serde(default)]
2116 #[serde(rename = "_meta")]
2117 pub meta: Option<Meta>,
2118}
2119
2120impl NesUserAction {
2121 #[must_use]
2123 pub fn new(
2124 action: impl Into<String>,
2125 uri: impl Into<String>,
2126 position: Position,
2127 timestamp_ms: u64,
2128 ) -> Self {
2129 Self {
2130 action: action.into(),
2131 uri: uri.into(),
2132 position,
2133 timestamp_ms,
2134 meta: None,
2135 }
2136 }
2137
2138 #[must_use]
2144 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2145 self.meta = meta.into_option();
2146 self
2147 }
2148}
2149
2150#[serde_as]
2152#[skip_serializing_none]
2153#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2154#[serde(rename_all = "camelCase")]
2155#[non_exhaustive]
2156pub struct NesOpenFile {
2157 #[schemars(url)]
2159 pub uri: String,
2160 pub language_id: String,
2162 #[serde_as(deserialize_as = "DefaultOnError")]
2164 #[schemars(extend("x-deserialize-default-on-error" = true))]
2165 #[serde(default)]
2166 pub visible_range: Option<Range>,
2167 #[serde_as(deserialize_as = "DefaultOnError")]
2169 #[schemars(extend("x-deserialize-default-on-error" = true))]
2170 #[serde(default)]
2171 pub last_focused_ms: Option<u64>,
2172 #[serde_as(deserialize_as = "DefaultOnError")]
2178 #[schemars(extend("x-deserialize-default-on-error" = true))]
2179 #[serde(default)]
2180 #[serde(rename = "_meta")]
2181 pub meta: Option<Meta>,
2182}
2183
2184impl NesOpenFile {
2185 #[must_use]
2187 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
2188 Self {
2189 uri: uri.into(),
2190 language_id: language_id.into(),
2191 visible_range: None,
2192 last_focused_ms: None,
2193 meta: None,
2194 }
2195 }
2196
2197 #[must_use]
2199 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
2200 self.visible_range = visible_range.into_option();
2201 self
2202 }
2203
2204 #[must_use]
2206 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
2207 self.last_focused_ms = last_focused_ms.into_option();
2208 self
2209 }
2210
2211 #[must_use]
2217 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2218 self.meta = meta.into_option();
2219 self
2220 }
2221}
2222
2223#[serde_as]
2225#[skip_serializing_none]
2226#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2227#[serde(rename_all = "camelCase")]
2228#[non_exhaustive]
2229pub struct NesDiagnostic {
2230 #[schemars(url)]
2232 pub uri: String,
2233 pub range: Range,
2235 pub severity: NesDiagnosticSeverity,
2237 pub message: String,
2239 #[serde_as(deserialize_as = "DefaultOnError")]
2245 #[schemars(extend("x-deserialize-default-on-error" = true))]
2246 #[serde(default)]
2247 #[serde(rename = "_meta")]
2248 pub meta: Option<Meta>,
2249}
2250
2251impl NesDiagnostic {
2252 #[must_use]
2254 pub fn new(
2255 uri: impl Into<String>,
2256 range: Range,
2257 severity: NesDiagnosticSeverity,
2258 message: impl Into<String>,
2259 ) -> Self {
2260 Self {
2261 uri: uri.into(),
2262 range,
2263 severity,
2264 message: message.into(),
2265 meta: None,
2266 }
2267 }
2268
2269 #[must_use]
2275 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2276 self.meta = meta.into_option();
2277 self
2278 }
2279}
2280
2281#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2283#[non_exhaustive]
2284pub enum NesDiagnosticSeverity {
2285 #[serde(rename = "error")]
2287 Error,
2288 #[serde(rename = "warning")]
2290 Warning,
2291 #[serde(rename = "information")]
2293 Information,
2294 #[serde(rename = "hint")]
2296 Hint,
2297 #[serde(untagged)]
2303 Other(String),
2304}
2305
2306#[serde_as]
2310#[skip_serializing_none]
2311#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2312#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
2313#[serde(rename_all = "camelCase")]
2314#[non_exhaustive]
2315pub struct SuggestNesResponse {
2316 pub suggestions: Vec<NesSuggestion>,
2318 #[serde_as(deserialize_as = "DefaultOnError")]
2324 #[schemars(extend("x-deserialize-default-on-error" = true))]
2325 #[serde(default)]
2326 #[serde(rename = "_meta")]
2327 pub meta: Option<Meta>,
2328}
2329
2330impl SuggestNesResponse {
2331 #[must_use]
2333 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2334 Self {
2335 suggestions,
2336 meta: None,
2337 }
2338 }
2339
2340 #[must_use]
2346 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2347 self.meta = meta.into_option();
2348 self
2349 }
2350}
2351
2352#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2354#[serde(tag = "kind", rename_all = "camelCase")]
2355#[schemars(extend("discriminator" = {"propertyName": "kind"}))]
2356#[non_exhaustive]
2357pub enum NesSuggestion {
2358 Edit(NesEditSuggestion),
2360 Jump(NesJumpSuggestion),
2362 Rename(NesRenameSuggestion),
2364 SearchAndReplace(NesSearchAndReplaceSuggestion),
2366 #[serde(untagged)]
2376 Other(OtherNesSuggestion),
2377}
2378
2379#[derive(Debug, Clone, Serialize, JsonSchema, PartialEq, Eq)]
2381#[schemars(inline)]
2382#[schemars(transform = other_nes_suggestion_schema)]
2383#[serde(rename_all = "camelCase")]
2384#[non_exhaustive]
2385pub struct OtherNesSuggestion {
2386 pub kind: String,
2392 pub suggestion_id: NesSuggestionId,
2394 #[serde(flatten)]
2396 pub fields: BTreeMap<String, serde_json::Value>,
2397}
2398
2399impl OtherNesSuggestion {
2400 #[must_use]
2402 pub fn new(
2403 kind: impl Into<String>,
2404 suggestion_id: impl Into<NesSuggestionId>,
2405 mut fields: BTreeMap<String, serde_json::Value>,
2406 ) -> Self {
2407 fields.remove("kind");
2408 fields.remove("suggestionId");
2409 Self {
2410 kind: kind.into(),
2411 suggestion_id: suggestion_id.into(),
2412 fields,
2413 }
2414 }
2415}
2416
2417impl<'de> Deserialize<'de> for OtherNesSuggestion {
2418 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2419 where
2420 D: serde::Deserializer<'de>,
2421 {
2422 let mut fields = BTreeMap::<String, serde_json::Value>::deserialize(deserializer)?;
2423 let kind = fields
2424 .remove("kind")
2425 .ok_or_else(|| serde::de::Error::missing_field("kind"))?;
2426 let serde_json::Value::String(kind) = kind else {
2427 return Err(serde::de::Error::custom("`kind` must be a string"));
2428 };
2429 let suggestion_id = fields
2430 .remove("suggestionId")
2431 .ok_or_else(|| serde::de::Error::missing_field("suggestionId"))?;
2432 let serde_json::Value::String(suggestion_id) = suggestion_id else {
2433 return Err(serde::de::Error::custom("`suggestionId` must be a string"));
2434 };
2435
2436 if is_known_nes_suggestion_kind(&kind) {
2437 return Err(serde::de::Error::custom(format!(
2438 "known NES suggestion `{kind}` did not match its schema"
2439 )));
2440 }
2441
2442 Ok(Self {
2443 kind,
2444 suggestion_id: NesSuggestionId::new(suggestion_id),
2445 fields,
2446 })
2447 }
2448}
2449
2450fn is_known_nes_suggestion_kind(kind: &str) -> bool {
2451 matches!(kind, "edit" | "jump" | "rename" | "searchAndReplace")
2452}
2453
2454fn other_nes_suggestion_schema(schema: &mut Schema) {
2455 super::schema_util::reject_known_string_discriminators(
2456 schema,
2457 "kind",
2458 &["edit", "jump", "rename", "searchAndReplace"],
2459 );
2460}
2461
2462#[serde_as]
2464#[skip_serializing_none]
2465#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2466#[serde(rename_all = "camelCase")]
2467#[non_exhaustive]
2468pub struct NesEditSuggestion {
2469 pub suggestion_id: NesSuggestionId,
2471 #[schemars(url)]
2473 pub uri: String,
2474 #[schemars(length(min = 1))]
2476 pub edits: Vec<NesTextEdit>,
2477 #[serde_as(deserialize_as = "DefaultOnError")]
2479 #[schemars(extend("x-deserialize-default-on-error" = true))]
2480 #[serde(default)]
2481 pub cursor_position: Option<Position>,
2482 #[serde_as(deserialize_as = "DefaultOnError")]
2488 #[schemars(extend("x-deserialize-default-on-error" = true))]
2489 #[serde(default)]
2490 #[serde(rename = "_meta")]
2491 pub meta: Option<Meta>,
2492}
2493
2494impl NesEditSuggestion {
2495 #[must_use]
2497 pub fn new(
2498 suggestion_id: impl Into<NesSuggestionId>,
2499 uri: impl Into<String>,
2500 edits: Vec<NesTextEdit>,
2501 ) -> Self {
2502 Self {
2503 suggestion_id: suggestion_id.into(),
2504 uri: uri.into(),
2505 edits,
2506 cursor_position: None,
2507 meta: None,
2508 }
2509 }
2510
2511 #[must_use]
2513 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2514 self.cursor_position = cursor_position.into_option();
2515 self
2516 }
2517
2518 #[must_use]
2524 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2525 self.meta = meta.into_option();
2526 self
2527 }
2528}
2529
2530#[serde_as]
2532#[skip_serializing_none]
2533#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2534#[serde(rename_all = "camelCase")]
2535#[non_exhaustive]
2536pub struct NesTextEdit {
2537 pub range: Range,
2539 pub new_text: String,
2541 #[serde_as(deserialize_as = "DefaultOnError")]
2547 #[schemars(extend("x-deserialize-default-on-error" = true))]
2548 #[serde(default)]
2549 #[serde(rename = "_meta")]
2550 pub meta: Option<Meta>,
2551}
2552
2553impl NesTextEdit {
2554 #[must_use]
2556 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2557 Self {
2558 range,
2559 new_text: new_text.into(),
2560 meta: None,
2561 }
2562 }
2563
2564 #[must_use]
2570 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2571 self.meta = meta.into_option();
2572 self
2573 }
2574}
2575
2576#[serde_as]
2578#[skip_serializing_none]
2579#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2580#[serde(rename_all = "camelCase")]
2581#[non_exhaustive]
2582pub struct NesJumpSuggestion {
2583 pub suggestion_id: NesSuggestionId,
2585 #[schemars(url)]
2587 pub uri: String,
2588 pub position: Position,
2590 #[serde_as(deserialize_as = "DefaultOnError")]
2596 #[schemars(extend("x-deserialize-default-on-error" = true))]
2597 #[serde(default)]
2598 #[serde(rename = "_meta")]
2599 pub meta: Option<Meta>,
2600}
2601
2602impl NesJumpSuggestion {
2603 #[must_use]
2605 pub fn new(
2606 suggestion_id: impl Into<NesSuggestionId>,
2607 uri: impl Into<String>,
2608 position: Position,
2609 ) -> Self {
2610 Self {
2611 suggestion_id: suggestion_id.into(),
2612 uri: uri.into(),
2613 position,
2614 meta: None,
2615 }
2616 }
2617
2618 #[must_use]
2624 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2625 self.meta = meta.into_option();
2626 self
2627 }
2628}
2629
2630#[serde_as]
2632#[skip_serializing_none]
2633#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2634#[serde(rename_all = "camelCase")]
2635#[non_exhaustive]
2636pub struct NesRenameSuggestion {
2637 pub suggestion_id: NesSuggestionId,
2639 #[schemars(url)]
2641 pub uri: String,
2642 pub position: Position,
2644 pub new_name: String,
2646 #[serde_as(deserialize_as = "DefaultOnError")]
2652 #[schemars(extend("x-deserialize-default-on-error" = true))]
2653 #[serde(default)]
2654 #[serde(rename = "_meta")]
2655 pub meta: Option<Meta>,
2656}
2657
2658impl NesRenameSuggestion {
2659 #[must_use]
2661 pub fn new(
2662 suggestion_id: impl Into<NesSuggestionId>,
2663 uri: impl Into<String>,
2664 position: Position,
2665 new_name: impl Into<String>,
2666 ) -> Self {
2667 Self {
2668 suggestion_id: suggestion_id.into(),
2669 uri: uri.into(),
2670 position,
2671 new_name: new_name.into(),
2672 meta: None,
2673 }
2674 }
2675
2676 #[must_use]
2682 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2683 self.meta = meta.into_option();
2684 self
2685 }
2686}
2687
2688#[serde_as]
2690#[skip_serializing_none]
2691#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2692#[serde(rename_all = "camelCase")]
2693#[non_exhaustive]
2694pub struct NesSearchAndReplaceSuggestion {
2695 pub suggestion_id: NesSuggestionId,
2697 #[schemars(url)]
2699 pub uri: String,
2700 pub search: String,
2702 pub replace: String,
2704 #[serde(default)]
2706 pub is_regex: Option<bool>,
2707 #[serde_as(deserialize_as = "DefaultOnError")]
2713 #[schemars(extend("x-deserialize-default-on-error" = true))]
2714 #[serde(default)]
2715 #[serde(rename = "_meta")]
2716 pub meta: Option<Meta>,
2717}
2718
2719impl NesSearchAndReplaceSuggestion {
2720 #[must_use]
2722 pub fn new(
2723 suggestion_id: impl Into<NesSuggestionId>,
2724 uri: impl Into<String>,
2725 search: impl Into<String>,
2726 replace: impl Into<String>,
2727 ) -> Self {
2728 Self {
2729 suggestion_id: suggestion_id.into(),
2730 uri: uri.into(),
2731 search: search.into(),
2732 replace: replace.into(),
2733 is_regex: None,
2734 meta: None,
2735 }
2736 }
2737
2738 #[must_use]
2740 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2741 self.is_regex = is_regex.into_option();
2742 self
2743 }
2744
2745 #[must_use]
2751 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2752 self.meta = meta.into_option();
2753 self
2754 }
2755}
2756
2757#[serde_as]
2761#[skip_serializing_none]
2762#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2763#[schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME))]
2764#[serde(rename_all = "camelCase")]
2765#[non_exhaustive]
2766pub struct AcceptNesNotification {
2767 pub session_id: SessionId,
2769 pub suggestion_id: NesSuggestionId,
2771 #[serde_as(deserialize_as = "DefaultOnError")]
2777 #[schemars(extend("x-deserialize-default-on-error" = true))]
2778 #[serde(default)]
2779 #[serde(rename = "_meta")]
2780 pub meta: Option<Meta>,
2781}
2782
2783impl AcceptNesNotification {
2784 #[must_use]
2786 pub fn new(
2787 session_id: impl Into<SessionId>,
2788 suggestion_id: impl Into<NesSuggestionId>,
2789 ) -> Self {
2790 Self {
2791 session_id: session_id.into(),
2792 suggestion_id: suggestion_id.into(),
2793 meta: None,
2794 }
2795 }
2796
2797 #[must_use]
2803 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2804 self.meta = meta.into_option();
2805 self
2806 }
2807}
2808
2809#[serde_as]
2811#[skip_serializing_none]
2812#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2813#[schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME))]
2814#[serde(rename_all = "camelCase")]
2815#[non_exhaustive]
2816pub struct RejectNesNotification {
2817 pub session_id: SessionId,
2819 pub suggestion_id: NesSuggestionId,
2821 #[serde_as(deserialize_as = "DefaultOnError")]
2823 #[schemars(extend("x-deserialize-default-on-error" = true))]
2824 #[serde(default)]
2825 pub reason: Option<NesRejectReason>,
2826 #[serde_as(deserialize_as = "DefaultOnError")]
2832 #[schemars(extend("x-deserialize-default-on-error" = true))]
2833 #[serde(default)]
2834 #[serde(rename = "_meta")]
2835 pub meta: Option<Meta>,
2836}
2837
2838impl RejectNesNotification {
2839 #[must_use]
2841 pub fn new(
2842 session_id: impl Into<SessionId>,
2843 suggestion_id: impl Into<NesSuggestionId>,
2844 ) -> Self {
2845 Self {
2846 session_id: session_id.into(),
2847 suggestion_id: suggestion_id.into(),
2848 reason: None,
2849 meta: None,
2850 }
2851 }
2852
2853 #[must_use]
2855 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2856 self.reason = reason.into_option();
2857 self
2858 }
2859
2860 #[must_use]
2866 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2867 self.meta = meta.into_option();
2868 self
2869 }
2870}
2871
2872#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2874#[non_exhaustive]
2875pub enum NesRejectReason {
2876 #[serde(rename = "rejected")]
2878 Rejected,
2879 #[serde(rename = "ignored")]
2881 Ignored,
2882 #[serde(rename = "replaced")]
2884 Replaced,
2885 #[serde(rename = "cancelled")]
2887 Cancelled,
2888 #[serde(untagged)]
2894 Other(String),
2895}
2896
2897#[cfg(test)]
2898mod tests {
2899 use super::*;
2900 use serde_json::json;
2901
2902 #[test]
2903 fn test_position_encoding_kind_serialization() {
2904 assert_eq!(
2905 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2906 json!("utf-16")
2907 );
2908 assert_eq!(
2909 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2910 json!("utf-32")
2911 );
2912 assert_eq!(
2913 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2914 json!("utf-8")
2915 );
2916
2917 assert_eq!(
2918 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2919 PositionEncodingKind::Utf16
2920 );
2921 assert_eq!(
2922 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2923 PositionEncodingKind::Utf32
2924 );
2925 assert_eq!(
2926 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2927 PositionEncodingKind::Utf8
2928 );
2929 assert!(serde_json::from_value::<PositionEncodingKind>(json!("_future")).is_err());
2930 }
2931
2932 #[test]
2933 fn test_client_capabilities_skip_unknown_position_encodings() {
2934 let caps: crate::v2::ClientCapabilities = serde_json::from_value(json!({
2935 "positionEncodings": ["_future", "utf-8", "utf-16"]
2936 }))
2937 .unwrap();
2938
2939 assert_eq!(
2940 caps.position_encodings,
2941 vec![PositionEncodingKind::Utf8, PositionEncodingKind::Utf16]
2942 );
2943 }
2944
2945 #[test]
2946 fn test_agent_nes_capabilities_serialization() {
2947 let caps = NesCapabilities::new()
2948 .events(
2949 NesEventCapabilities::new().document(
2950 NesDocumentEventCapabilities::new()
2951 .did_open(NesDocumentDidOpenCapabilities::default())
2952 .did_change(NesDocumentDidChangeCapabilities::new(
2953 TextDocumentSyncKind::Incremental,
2954 ))
2955 .did_close(NesDocumentDidCloseCapabilities::default())
2956 .did_save(NesDocumentDidSaveCapabilities::default())
2957 .did_focus(NesDocumentDidFocusCapabilities::default()),
2958 ),
2959 )
2960 .context(
2961 NesContextCapabilities::new()
2962 .recent_files(NesRecentFilesCapabilities {
2963 max_count: Some(10),
2964 meta: None,
2965 })
2966 .related_snippets(NesRelatedSnippetsCapabilities::default())
2967 .edit_history(NesEditHistoryCapabilities {
2968 max_count: Some(6),
2969 meta: None,
2970 })
2971 .user_actions(NesUserActionsCapabilities {
2972 max_count: Some(16),
2973 meta: None,
2974 })
2975 .open_files(NesOpenFilesCapabilities::default())
2976 .diagnostics(NesDiagnosticsCapabilities::default()),
2977 );
2978
2979 let json = serde_json::to_value(&caps).unwrap();
2980 assert_eq!(
2981 json,
2982 json!({
2983 "events": {
2984 "document": {
2985 "didOpen": {},
2986 "didChange": {
2987 "syncKind": "incremental"
2988 },
2989 "didClose": {},
2990 "didSave": {},
2991 "didFocus": {}
2992 }
2993 },
2994 "context": {
2995 "recentFiles": {
2996 "maxCount": 10
2997 },
2998 "relatedSnippets": {},
2999 "editHistory": {
3000 "maxCount": 6
3001 },
3002 "userActions": {
3003 "maxCount": 16
3004 },
3005 "openFiles": {},
3006 "diagnostics": {}
3007 }
3008 })
3009 );
3010
3011 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
3013 assert_eq!(deserialized, caps);
3014 }
3015
3016 #[test]
3017 fn test_client_nes_capabilities_serialization() {
3018 let caps = ClientNesCapabilities::new()
3019 .jump(NesJumpCapabilities::default())
3020 .rename(NesRenameCapabilities::default())
3021 .search_and_replace(NesSearchAndReplaceCapabilities::default());
3022
3023 let json = serde_json::to_value(&caps).unwrap();
3024 assert_eq!(
3025 json,
3026 json!({
3027 "jump": {},
3028 "rename": {},
3029 "searchAndReplace": {}
3030 })
3031 );
3032
3033 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
3034 assert_eq!(deserialized, caps);
3035 }
3036
3037 #[test]
3038 fn test_document_did_open_serialization() {
3039 let notification = DidOpenDocumentNotification::new(
3040 "session_123",
3041 "file:///path/to/file.rs",
3042 "rust",
3043 1,
3044 "fn main() {\n println!(\"hello\");\n}\n",
3045 );
3046
3047 let json = serde_json::to_value(¬ification).unwrap();
3048 assert_eq!(
3049 json,
3050 json!({
3051 "sessionId": "session_123",
3052 "uri": "file:///path/to/file.rs",
3053 "languageId": "rust",
3054 "version": 1,
3055 "text": "fn main() {\n println!(\"hello\");\n}\n"
3056 })
3057 );
3058
3059 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
3060 assert_eq!(deserialized, notification);
3061 }
3062
3063 #[test]
3064 fn test_document_did_change_incremental_serialization() {
3065 let notification = DidChangeDocumentNotification::new(
3066 "session_123",
3067 "file:///path/to/file.rs",
3068 2,
3069 vec![TextDocumentContentChangeEvent::incremental(
3070 Range::new(Position::new(1, 4), Position::new(1, 4)),
3071 "let x = 42;\n ",
3072 )],
3073 );
3074
3075 let json = serde_json::to_value(¬ification).unwrap();
3076 assert_eq!(
3077 json,
3078 json!({
3079 "sessionId": "session_123",
3080 "uri": "file:///path/to/file.rs",
3081 "version": 2,
3082 "contentChanges": [
3083 {
3084 "range": {
3085 "start": { "line": 1, "character": 4 },
3086 "end": { "line": 1, "character": 4 }
3087 },
3088 "text": "let x = 42;\n "
3089 }
3090 ]
3091 })
3092 );
3093 }
3094
3095 #[test]
3096 fn test_document_did_change_full_serialization() {
3097 let notification = DidChangeDocumentNotification::new(
3098 "session_123",
3099 "file:///path/to/file.rs",
3100 2,
3101 vec![TextDocumentContentChangeEvent::full(
3102 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
3103 )],
3104 );
3105
3106 let json = serde_json::to_value(¬ification).unwrap();
3107 assert_eq!(
3108 json,
3109 json!({
3110 "sessionId": "session_123",
3111 "uri": "file:///path/to/file.rs",
3112 "version": 2,
3113 "contentChanges": [
3114 {
3115 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
3116 }
3117 ]
3118 })
3119 );
3120 }
3121
3122 #[test]
3123 fn test_document_did_close_serialization() {
3124 let notification =
3125 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
3126 let json = serde_json::to_value(¬ification).unwrap();
3127 assert_eq!(
3128 json,
3129 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3130 );
3131 }
3132
3133 #[test]
3134 fn test_document_did_save_serialization() {
3135 let notification =
3136 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
3137 let json = serde_json::to_value(¬ification).unwrap();
3138 assert_eq!(
3139 json,
3140 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3141 );
3142 }
3143
3144 #[test]
3145 fn test_document_did_focus_serialization() {
3146 let notification = DidFocusDocumentNotification::new(
3147 "session_123",
3148 "file:///path/to/file.rs",
3149 2,
3150 Position::new(5, 12),
3151 Range::new(Position::new(0, 0), Position::new(45, 0)),
3152 );
3153
3154 let json = serde_json::to_value(¬ification).unwrap();
3155 assert_eq!(
3156 json,
3157 json!({
3158 "sessionId": "session_123",
3159 "uri": "file:///path/to/file.rs",
3160 "version": 2,
3161 "position": { "line": 5, "character": 12 },
3162 "visibleRange": {
3163 "start": { "line": 0, "character": 0 },
3164 "end": { "line": 45, "character": 0 }
3165 }
3166 })
3167 );
3168 }
3169
3170 #[test]
3171 fn test_nes_suggestion_edit_serialization() {
3172 let suggestion = NesSuggestion::Edit(
3173 NesEditSuggestion::new(
3174 "sugg_001",
3175 "file:///path/to/other_file.rs",
3176 vec![NesTextEdit::new(
3177 Range::new(Position::new(5, 0), Position::new(5, 10)),
3178 "let result = helper();",
3179 )],
3180 )
3181 .cursor_position(Position::new(5, 22)),
3182 );
3183
3184 let json = serde_json::to_value(&suggestion).unwrap();
3185 assert_eq!(
3186 json,
3187 json!({
3188 "kind": "edit",
3189 "suggestionId": "sugg_001",
3190 "uri": "file:///path/to/other_file.rs",
3191 "edits": [
3192 {
3193 "range": {
3194 "start": { "line": 5, "character": 0 },
3195 "end": { "line": 5, "character": 10 }
3196 },
3197 "newText": "let result = helper();"
3198 }
3199 ],
3200 "cursorPosition": { "line": 5, "character": 22 }
3201 })
3202 );
3203
3204 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3205 assert_eq!(deserialized, suggestion);
3206 }
3207
3208 #[test]
3209 fn test_nes_suggestion_unknown_variant() {
3210 let suggestion: NesSuggestion = serde_json::from_value(json!({
3211 "kind": "_preview",
3212 "suggestionId": "sugg_001",
3213 "label": "Preview generated file"
3214 }))
3215 .unwrap();
3216
3217 let NesSuggestion::Other(unknown) = suggestion else {
3218 panic!("expected unknown NES suggestion");
3219 };
3220
3221 assert_eq!(unknown.kind, "_preview");
3222 assert_eq!(unknown.suggestion_id.to_string(), "sugg_001");
3223 assert!(!unknown.fields.contains_key("suggestionId"));
3224 assert_eq!(
3225 serde_json::to_value(NesSuggestion::Other(unknown)).unwrap(),
3226 json!({
3227 "kind": "_preview",
3228 "suggestionId": "sugg_001",
3229 "label": "Preview generated file"
3230 })
3231 );
3232 }
3233
3234 #[test]
3235 fn test_nes_suggestion_unknown_does_not_hide_malformed_known_variant() {
3236 assert!(
3237 serde_json::from_value::<NesSuggestion>(json!({
3238 "kind": "edit"
3239 }))
3240 .is_err()
3241 );
3242 }
3243
3244 #[test]
3245 fn test_nes_suggestion_jump_serialization() {
3246 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
3247 "sugg_002",
3248 "file:///path/to/other_file.rs",
3249 Position::new(15, 4),
3250 ));
3251
3252 let json = serde_json::to_value(&suggestion).unwrap();
3253 assert_eq!(
3254 json,
3255 json!({
3256 "kind": "jump",
3257 "suggestionId": "sugg_002",
3258 "uri": "file:///path/to/other_file.rs",
3259 "position": { "line": 15, "character": 4 }
3260 })
3261 );
3262
3263 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3264 assert_eq!(deserialized, suggestion);
3265 }
3266
3267 #[test]
3268 fn test_nes_suggestion_rename_serialization() {
3269 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
3270 "sugg_003",
3271 "file:///path/to/file.rs",
3272 Position::new(5, 10),
3273 "calculateTotal",
3274 ));
3275
3276 let json = serde_json::to_value(&suggestion).unwrap();
3277 assert_eq!(
3278 json,
3279 json!({
3280 "kind": "rename",
3281 "suggestionId": "sugg_003",
3282 "uri": "file:///path/to/file.rs",
3283 "position": { "line": 5, "character": 10 },
3284 "newName": "calculateTotal"
3285 })
3286 );
3287
3288 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3289 assert_eq!(deserialized, suggestion);
3290 }
3291
3292 #[test]
3293 fn test_nes_suggestion_search_and_replace_serialization() {
3294 let suggestion = NesSuggestion::SearchAndReplace(
3295 NesSearchAndReplaceSuggestion::new(
3296 "sugg_004",
3297 "file:///path/to/file.rs",
3298 "oldFunction",
3299 "newFunction",
3300 )
3301 .is_regex(false),
3302 );
3303
3304 let json = serde_json::to_value(&suggestion).unwrap();
3305 assert_eq!(
3306 json,
3307 json!({
3308 "kind": "searchAndReplace",
3309 "suggestionId": "sugg_004",
3310 "uri": "file:///path/to/file.rs",
3311 "search": "oldFunction",
3312 "replace": "newFunction",
3313 "isRegex": false
3314 })
3315 );
3316
3317 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3318 assert_eq!(deserialized, suggestion);
3319 }
3320
3321 #[test]
3322 fn test_nes_start_request_serialization() {
3323 let request = StartNesRequest::new()
3324 .workspace_uri("file:///Users/alice/projects/my-app")
3325 .workspace_folders(vec![WorkspaceFolder::new(
3326 "file:///Users/alice/projects/my-app",
3327 "my-app",
3328 )])
3329 .repository(NesRepository::new(
3330 "my-app",
3331 "alice",
3332 "https://github.com/alice/my-app.git",
3333 ));
3334
3335 let json = serde_json::to_value(&request).unwrap();
3336 assert_eq!(
3337 json,
3338 json!({
3339 "workspaceUri": "file:///Users/alice/projects/my-app",
3340 "workspaceFolders": [
3341 {
3342 "uri": "file:///Users/alice/projects/my-app",
3343 "name": "my-app"
3344 }
3345 ],
3346 "repository": {
3347 "name": "my-app",
3348 "owner": "alice",
3349 "remoteUrl": "https://github.com/alice/my-app.git"
3350 }
3351 })
3352 );
3353 }
3354
3355 #[test]
3356 fn test_nes_start_response_serialization() {
3357 let response = StartNesResponse::new("session_abc123");
3358 let json = serde_json::to_value(&response).unwrap();
3359 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
3360 }
3361
3362 #[test]
3363 fn test_nes_trigger_kind_serialization() {
3364 assert_eq!(
3365 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
3366 json!("automatic")
3367 );
3368 assert_eq!(
3369 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
3370 json!("diagnostic")
3371 );
3372 assert_eq!(
3373 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
3374 json!("manual")
3375 );
3376 }
3377
3378 #[test]
3379 fn test_nes_reject_reason_serialization() {
3380 assert_eq!(
3381 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
3382 json!("rejected")
3383 );
3384 assert_eq!(
3385 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
3386 json!("ignored")
3387 );
3388 assert_eq!(
3389 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
3390 json!("replaced")
3391 );
3392 assert_eq!(
3393 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
3394 json!("cancelled")
3395 );
3396 }
3397
3398 #[test]
3399 fn test_nes_accept_notification_serialization() {
3400 let notification = AcceptNesNotification::new("session_123", "sugg_001");
3401 let json = serde_json::to_value(¬ification).unwrap();
3402 assert_eq!(
3403 json,
3404 json!({ "sessionId": "session_123", "suggestionId": "sugg_001" })
3405 );
3406 }
3407
3408 #[test]
3409 fn test_nes_reject_notification_serialization() {
3410 let notification =
3411 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
3412 let json = serde_json::to_value(¬ification).unwrap();
3413 assert_eq!(
3414 json,
3415 json!({ "sessionId": "session_123", "suggestionId": "sugg_001", "reason": "rejected" })
3416 );
3417 }
3418
3419 #[test]
3420 fn test_nes_suggest_request_with_context_serialization() {
3421 let request = SuggestNesRequest::new(
3422 "session_123",
3423 "file:///path/to/file.rs",
3424 2,
3425 Position::new(5, 12),
3426 NesTriggerKind::Automatic,
3427 )
3428 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
3429 .context(
3430 NesSuggestContext::new()
3431 .recent_files(vec![NesRecentFile::new(
3432 "file:///path/to/utils.rs",
3433 "rust",
3434 "pub fn helper() -> i32 { 42 }\n",
3435 )])
3436 .diagnostics(vec![NesDiagnostic::new(
3437 "file:///path/to/file.rs",
3438 Range::new(Position::new(5, 0), Position::new(5, 10)),
3439 NesDiagnosticSeverity::Error,
3440 "cannot find value `foo` in this scope",
3441 )]),
3442 );
3443
3444 let json = serde_json::to_value(&request).unwrap();
3445 assert_eq!(json["sessionId"], "session_123");
3446 assert_eq!(json["uri"], "file:///path/to/file.rs");
3447 assert_eq!(json["version"], 2);
3448 assert_eq!(json["triggerKind"], "automatic");
3449 assert_eq!(
3450 json["context"]["recentFiles"][0]["uri"],
3451 "file:///path/to/utils.rs"
3452 );
3453 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
3454 }
3455
3456 #[test]
3457 fn test_text_document_sync_kind_serialization() {
3458 assert_eq!(
3459 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
3460 json!("full")
3461 );
3462 assert_eq!(
3463 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
3464 json!("incremental")
3465 );
3466 assert!(serde_json::from_value::<TextDocumentSyncKind>(json!("_future")).is_err());
3467 }
3468
3469 #[test]
3470 fn test_document_event_capabilities_drop_unknown_did_change_sync_kind() {
3471 let caps: NesDocumentEventCapabilities = serde_json::from_value(json!({
3472 "didChange": {
3473 "syncKind": "_future"
3474 }
3475 }))
3476 .unwrap();
3477
3478 assert_eq!(caps.did_change, None);
3479 }
3480
3481 #[test]
3482 fn test_document_did_change_capabilities_requires_sync_kind() {
3483 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
3484 }
3485
3486 #[test]
3487 fn test_nes_suggest_response_serialization() {
3488 let response = SuggestNesResponse::new(vec![
3489 NesSuggestion::Edit(NesEditSuggestion::new(
3490 "sugg_001",
3491 "file:///path/to/file.rs",
3492 vec![NesTextEdit::new(
3493 Range::new(Position::new(5, 0), Position::new(5, 10)),
3494 "let result = helper();",
3495 )],
3496 )),
3497 NesSuggestion::Jump(NesJumpSuggestion::new(
3498 "sugg_002",
3499 "file:///path/to/other.rs",
3500 Position::new(10, 0),
3501 )),
3502 ]);
3503
3504 let json = serde_json::to_value(&response).unwrap();
3505 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3506 assert_eq!(json["suggestions"][0]["kind"], "edit");
3507 assert_eq!(json["suggestions"][1]["kind"], "jump");
3508 }
3509}