1use std::{collections::BTreeMap, sync::Arc};
8
9use derive_more::{Display, From};
10#[cfg(feature = "schemars")]
11use schemars::Schema;
12use serde::{Deserialize, Serialize};
13use serde_with::{DefaultOnError, VecSkipError, serde_as, skip_serializing_none};
14
15use super::{Meta, SessionId};
16use crate::{IntoOption, SkipListener};
17
18pub(crate) const NES_START_METHOD_NAME: &str = "nes/start";
22pub(crate) const NES_SUGGEST_METHOD_NAME: &str = "nes/suggest";
24pub(crate) const NES_ACCEPT_METHOD_NAME: &str = "nes/accept";
26pub(crate) const NES_REJECT_METHOD_NAME: &str = "nes/reject";
28
29#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
35#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Display, From)]
36#[serde(transparent)]
37#[from(forward)]
38#[non_exhaustive]
39pub struct NesSuggestionId(pub Arc<str>);
40
41impl NesSuggestionId {
42 #[must_use]
44 pub fn new(id: impl Into<Self>) -> Self {
45 id.into()
46 }
47}
48pub(crate) const NES_CLOSE_METHOD_NAME: &str = "nes/close";
50pub(crate) const DOCUMENT_DID_OPEN_METHOD_NAME: &str = "document/didOpen";
52pub(crate) const DOCUMENT_DID_CHANGE_METHOD_NAME: &str = "document/didChange";
54pub(crate) const DOCUMENT_DID_CLOSE_METHOD_NAME: &str = "document/didClose";
56pub(crate) const DOCUMENT_DID_SAVE_METHOD_NAME: &str = "document/didSave";
58pub(crate) const DOCUMENT_DID_FOCUS_METHOD_NAME: &str = "document/didFocus";
60
61#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
67#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
68#[non_exhaustive]
69pub enum PositionEncodingKind {
70 #[serde(rename = "utf-16")]
72 Utf16,
73 #[serde(rename = "utf-32")]
75 Utf32,
76 #[serde(rename = "utf-8")]
78 Utf8,
79}
80
81#[serde_as]
85#[skip_serializing_none]
86#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
87#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
88#[serde(rename_all = "camelCase")]
89#[non_exhaustive]
90pub struct Position {
91 pub line: u32,
93 pub character: u32,
95 #[serde_as(deserialize_as = "DefaultOnError")]
101 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
102 #[serde(default)]
103 #[serde(rename = "_meta")]
104 pub meta: Option<Meta>,
105}
106
107impl Position {
108 #[must_use]
110 pub fn new(line: u32, character: u32) -> Self {
111 Self {
112 line,
113 character,
114 meta: None,
115 }
116 }
117
118 #[must_use]
124 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
125 self.meta = meta.into_option();
126 self
127 }
128}
129
130#[serde_as]
132#[skip_serializing_none]
133#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
134#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
135#[serde(rename_all = "camelCase")]
136#[non_exhaustive]
137pub struct Range {
138 pub start: Position,
140 pub end: Position,
142 #[serde_as(deserialize_as = "DefaultOnError")]
148 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
149 #[serde(default)]
150 #[serde(rename = "_meta")]
151 pub meta: Option<Meta>,
152}
153
154impl Range {
155 #[must_use]
157 pub fn new(start: Position, end: Position) -> Self {
158 Self {
159 start,
160 end,
161 meta: None,
162 }
163 }
164
165 #[must_use]
171 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
172 self.meta = meta.into_option();
173 self
174 }
175}
176
177#[serde_as]
184#[skip_serializing_none]
185#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
186#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
187#[serde(rename_all = "camelCase")]
188#[non_exhaustive]
189pub struct NesCapabilities {
190 #[serde_as(deserialize_as = "DefaultOnError")]
192 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
193 #[serde(default)]
194 pub events: Option<NesEventCapabilities>,
195 #[serde_as(deserialize_as = "DefaultOnError")]
197 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
198 #[serde(default)]
199 pub context: Option<NesContextCapabilities>,
200 #[serde_as(deserialize_as = "DefaultOnError")]
206 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
207 #[serde(default)]
208 #[serde(rename = "_meta")]
209 pub meta: Option<Meta>,
210}
211
212impl NesCapabilities {
213 #[must_use]
215 pub fn new() -> Self {
216 Self::default()
217 }
218
219 #[must_use]
221 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
222 self.events = events.into_option();
223 self
224 }
225
226 #[must_use]
228 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
229 self.context = context.into_option();
230 self
231 }
232
233 #[must_use]
239 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
240 self.meta = meta.into_option();
241 self
242 }
243}
244
245#[serde_as]
247#[skip_serializing_none]
248#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
249#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
250#[serde(rename_all = "camelCase")]
251#[non_exhaustive]
252pub struct NesEventCapabilities {
253 #[serde_as(deserialize_as = "DefaultOnError")]
255 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
256 #[serde(default)]
257 pub document: Option<NesDocumentEventCapabilities>,
258 #[serde_as(deserialize_as = "DefaultOnError")]
264 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
265 #[serde(default)]
266 #[serde(rename = "_meta")]
267 pub meta: Option<Meta>,
268}
269
270impl NesEventCapabilities {
271 #[must_use]
273 pub fn new() -> Self {
274 Self::default()
275 }
276
277 #[must_use]
279 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
280 self.document = document.into_option();
281 self
282 }
283
284 #[must_use]
290 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
291 self.meta = meta.into_option();
292 self
293 }
294}
295
296#[serde_as]
298#[skip_serializing_none]
299#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
300#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
301#[serde(rename_all = "camelCase")]
302#[non_exhaustive]
303pub struct NesDocumentEventCapabilities {
304 #[serde_as(deserialize_as = "DefaultOnError")]
306 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
307 #[serde(default)]
308 pub did_open: Option<NesDocumentDidOpenCapabilities>,
309 #[serde_as(deserialize_as = "DefaultOnError")]
311 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
312 #[serde(default)]
313 pub did_change: Option<NesDocumentDidChangeCapabilities>,
314 #[serde_as(deserialize_as = "DefaultOnError")]
316 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
317 #[serde(default)]
318 pub did_close: Option<NesDocumentDidCloseCapabilities>,
319 #[serde_as(deserialize_as = "DefaultOnError")]
321 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
322 #[serde(default)]
323 pub did_save: Option<NesDocumentDidSaveCapabilities>,
324 #[serde_as(deserialize_as = "DefaultOnError")]
326 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
327 #[serde(default)]
328 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
329 #[serde_as(deserialize_as = "DefaultOnError")]
335 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
336 #[serde(default)]
337 #[serde(rename = "_meta")]
338 pub meta: Option<Meta>,
339}
340
341impl NesDocumentEventCapabilities {
342 #[must_use]
344 pub fn new() -> Self {
345 Self::default()
346 }
347
348 #[must_use]
350 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
351 self.did_open = did_open.into_option();
352 self
353 }
354
355 #[must_use]
357 pub fn did_change(
358 mut self,
359 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
360 ) -> Self {
361 self.did_change = did_change.into_option();
362 self
363 }
364
365 #[must_use]
367 pub fn did_close(
368 mut self,
369 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
370 ) -> Self {
371 self.did_close = did_close.into_option();
372 self
373 }
374
375 #[must_use]
377 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
378 self.did_save = did_save.into_option();
379 self
380 }
381
382 #[must_use]
384 pub fn did_focus(
385 mut self,
386 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
387 ) -> Self {
388 self.did_focus = did_focus.into_option();
389 self
390 }
391
392 #[must_use]
398 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
399 self.meta = meta.into_option();
400 self
401 }
402}
403
404#[serde_as]
406#[skip_serializing_none]
407#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
408#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
409#[serde(rename_all = "camelCase")]
410#[non_exhaustive]
411pub struct NesDocumentDidOpenCapabilities {
412 #[serde_as(deserialize_as = "DefaultOnError")]
418 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
419 #[serde(default)]
420 #[serde(rename = "_meta")]
421 pub meta: Option<Meta>,
422}
423
424impl NesDocumentDidOpenCapabilities {
425 #[must_use]
427 pub fn new() -> Self {
428 Self::default()
429 }
430}
431
432#[serde_as]
434#[skip_serializing_none]
435#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
436#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
437#[serde(rename_all = "camelCase")]
438#[non_exhaustive]
439pub struct NesDocumentDidChangeCapabilities {
440 pub sync_kind: TextDocumentSyncKind,
442 #[serde_as(deserialize_as = "DefaultOnError")]
448 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
449 #[serde(default)]
450 #[serde(rename = "_meta")]
451 pub meta: Option<Meta>,
452}
453
454impl NesDocumentDidChangeCapabilities {
455 #[must_use]
457 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
458 Self {
459 sync_kind,
460 meta: None,
461 }
462 }
463
464 #[must_use]
470 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
471 self.meta = meta.into_option();
472 self
473 }
474}
475
476#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
478#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
479#[non_exhaustive]
480pub enum TextDocumentSyncKind {
481 #[serde(rename = "full")]
483 Full,
484 #[serde(rename = "incremental")]
486 Incremental,
487}
488
489#[serde_as]
491#[skip_serializing_none]
492#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
493#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
494#[serde(rename_all = "camelCase")]
495#[non_exhaustive]
496pub struct NesDocumentDidCloseCapabilities {
497 #[serde_as(deserialize_as = "DefaultOnError")]
503 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
504 #[serde(default)]
505 #[serde(rename = "_meta")]
506 pub meta: Option<Meta>,
507}
508
509impl NesDocumentDidCloseCapabilities {
510 #[must_use]
512 pub fn new() -> Self {
513 Self::default()
514 }
515}
516
517#[serde_as]
519#[skip_serializing_none]
520#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
521#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
522#[serde(rename_all = "camelCase")]
523#[non_exhaustive]
524pub struct NesDocumentDidSaveCapabilities {
525 #[serde_as(deserialize_as = "DefaultOnError")]
531 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
532 #[serde(default)]
533 #[serde(rename = "_meta")]
534 pub meta: Option<Meta>,
535}
536
537impl NesDocumentDidSaveCapabilities {
538 #[must_use]
540 pub fn new() -> Self {
541 Self::default()
542 }
543}
544
545#[serde_as]
547#[skip_serializing_none]
548#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
549#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
550#[serde(rename_all = "camelCase")]
551#[non_exhaustive]
552pub struct NesDocumentDidFocusCapabilities {
553 #[serde_as(deserialize_as = "DefaultOnError")]
559 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
560 #[serde(default)]
561 #[serde(rename = "_meta")]
562 pub meta: Option<Meta>,
563}
564
565impl NesDocumentDidFocusCapabilities {
566 #[must_use]
568 pub fn new() -> Self {
569 Self::default()
570 }
571}
572
573#[serde_as]
575#[skip_serializing_none]
576#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
577#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
578#[serde(rename_all = "camelCase")]
579#[non_exhaustive]
580pub struct NesContextCapabilities {
581 #[serde_as(deserialize_as = "DefaultOnError")]
583 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
584 #[serde(default)]
585 pub recent_files: Option<NesRecentFilesCapabilities>,
586 #[serde_as(deserialize_as = "DefaultOnError")]
588 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
589 #[serde(default)]
590 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
591 #[serde_as(deserialize_as = "DefaultOnError")]
593 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
594 #[serde(default)]
595 pub edit_history: Option<NesEditHistoryCapabilities>,
596 #[serde_as(deserialize_as = "DefaultOnError")]
598 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
599 #[serde(default)]
600 pub user_actions: Option<NesUserActionsCapabilities>,
601 #[serde_as(deserialize_as = "DefaultOnError")]
603 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
604 #[serde(default)]
605 pub open_files: Option<NesOpenFilesCapabilities>,
606 #[serde_as(deserialize_as = "DefaultOnError")]
608 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
609 #[serde(default)]
610 pub diagnostics: Option<NesDiagnosticsCapabilities>,
611 #[serde_as(deserialize_as = "DefaultOnError")]
617 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
618 #[serde(default)]
619 #[serde(rename = "_meta")]
620 pub meta: Option<Meta>,
621}
622
623impl NesContextCapabilities {
624 #[must_use]
626 pub fn new() -> Self {
627 Self::default()
628 }
629
630 #[must_use]
632 pub fn recent_files(
633 mut self,
634 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
635 ) -> Self {
636 self.recent_files = recent_files.into_option();
637 self
638 }
639
640 #[must_use]
642 pub fn related_snippets(
643 mut self,
644 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
645 ) -> Self {
646 self.related_snippets = related_snippets.into_option();
647 self
648 }
649
650 #[must_use]
652 pub fn edit_history(
653 mut self,
654 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
655 ) -> Self {
656 self.edit_history = edit_history.into_option();
657 self
658 }
659
660 #[must_use]
662 pub fn user_actions(
663 mut self,
664 user_actions: impl IntoOption<NesUserActionsCapabilities>,
665 ) -> Self {
666 self.user_actions = user_actions.into_option();
667 self
668 }
669
670 #[must_use]
672 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
673 self.open_files = open_files.into_option();
674 self
675 }
676
677 #[must_use]
679 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
680 self.diagnostics = diagnostics.into_option();
681 self
682 }
683
684 #[must_use]
690 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
691 self.meta = meta.into_option();
692 self
693 }
694}
695
696#[serde_as]
698#[skip_serializing_none]
699#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
700#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
701#[serde(rename_all = "camelCase")]
702#[non_exhaustive]
703pub struct NesRecentFilesCapabilities {
704 #[serde_as(deserialize_as = "DefaultOnError")]
706 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
707 #[serde(default)]
708 pub max_count: Option<u32>,
709 #[serde_as(deserialize_as = "DefaultOnError")]
715 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
716 #[serde(default)]
717 #[serde(rename = "_meta")]
718 pub meta: Option<Meta>,
719}
720
721impl NesRecentFilesCapabilities {
722 #[must_use]
724 pub fn new() -> Self {
725 Self::default()
726 }
727}
728
729#[serde_as]
731#[skip_serializing_none]
732#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
733#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
734#[serde(rename_all = "camelCase")]
735#[non_exhaustive]
736pub struct NesRelatedSnippetsCapabilities {
737 #[serde_as(deserialize_as = "DefaultOnError")]
743 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
744 #[serde(default)]
745 #[serde(rename = "_meta")]
746 pub meta: Option<Meta>,
747}
748
749impl NesRelatedSnippetsCapabilities {
750 #[must_use]
752 pub fn new() -> Self {
753 Self::default()
754 }
755}
756
757#[serde_as]
759#[skip_serializing_none]
760#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
761#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
762#[serde(rename_all = "camelCase")]
763#[non_exhaustive]
764pub struct NesEditHistoryCapabilities {
765 #[serde_as(deserialize_as = "DefaultOnError")]
767 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
768 #[serde(default)]
769 pub max_count: Option<u32>,
770 #[serde_as(deserialize_as = "DefaultOnError")]
776 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
777 #[serde(default)]
778 #[serde(rename = "_meta")]
779 pub meta: Option<Meta>,
780}
781
782impl NesEditHistoryCapabilities {
783 #[must_use]
785 pub fn new() -> Self {
786 Self::default()
787 }
788}
789
790#[serde_as]
792#[skip_serializing_none]
793#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
794#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
795#[serde(rename_all = "camelCase")]
796#[non_exhaustive]
797pub struct NesUserActionsCapabilities {
798 #[serde_as(deserialize_as = "DefaultOnError")]
800 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
801 #[serde(default)]
802 pub max_count: Option<u32>,
803 #[serde_as(deserialize_as = "DefaultOnError")]
809 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
810 #[serde(default)]
811 #[serde(rename = "_meta")]
812 pub meta: Option<Meta>,
813}
814
815impl NesUserActionsCapabilities {
816 #[must_use]
818 pub fn new() -> Self {
819 Self::default()
820 }
821}
822
823#[serde_as]
825#[skip_serializing_none]
826#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
827#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
828#[serde(rename_all = "camelCase")]
829#[non_exhaustive]
830pub struct NesOpenFilesCapabilities {
831 #[serde_as(deserialize_as = "DefaultOnError")]
837 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
838 #[serde(default)]
839 #[serde(rename = "_meta")]
840 pub meta: Option<Meta>,
841}
842
843impl NesOpenFilesCapabilities {
844 #[must_use]
846 pub fn new() -> Self {
847 Self::default()
848 }
849}
850
851#[serde_as]
853#[skip_serializing_none]
854#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
855#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
856#[serde(rename_all = "camelCase")]
857#[non_exhaustive]
858pub struct NesDiagnosticsCapabilities {
859 #[serde_as(deserialize_as = "DefaultOnError")]
865 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
866 #[serde(default)]
867 #[serde(rename = "_meta")]
868 pub meta: Option<Meta>,
869}
870
871impl NesDiagnosticsCapabilities {
872 #[must_use]
874 pub fn new() -> Self {
875 Self::default()
876 }
877}
878
879#[serde_as]
883#[skip_serializing_none]
884#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
885#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
886#[serde(rename_all = "camelCase")]
887#[non_exhaustive]
888pub struct ClientNesCapabilities {
889 #[serde_as(deserialize_as = "DefaultOnError")]
891 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
892 #[serde(default)]
893 pub jump: Option<NesJumpCapabilities>,
894 #[serde_as(deserialize_as = "DefaultOnError")]
896 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
897 #[serde(default)]
898 pub rename: Option<NesRenameCapabilities>,
899 #[serde_as(deserialize_as = "DefaultOnError")]
901 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
902 #[serde(default)]
903 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
904 #[serde_as(deserialize_as = "DefaultOnError")]
910 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
911 #[serde(default)]
912 #[serde(rename = "_meta")]
913 pub meta: Option<Meta>,
914}
915
916impl ClientNesCapabilities {
917 #[must_use]
919 pub fn new() -> Self {
920 Self::default()
921 }
922
923 #[must_use]
925 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
926 self.jump = jump.into_option();
927 self
928 }
929
930 #[must_use]
932 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
933 self.rename = rename.into_option();
934 self
935 }
936
937 #[must_use]
939 pub fn search_and_replace(
940 mut self,
941 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
942 ) -> Self {
943 self.search_and_replace = search_and_replace.into_option();
944 self
945 }
946
947 #[must_use]
953 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
954 self.meta = meta.into_option();
955 self
956 }
957}
958
959#[serde_as]
961#[skip_serializing_none]
962#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
963#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
964#[serde(rename_all = "camelCase")]
965#[non_exhaustive]
966pub struct NesJumpCapabilities {
967 #[serde_as(deserialize_as = "DefaultOnError")]
973 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
974 #[serde(default)]
975 #[serde(rename = "_meta")]
976 pub meta: Option<Meta>,
977}
978
979impl NesJumpCapabilities {
980 #[must_use]
982 pub fn new() -> Self {
983 Self::default()
984 }
985}
986
987#[serde_as]
989#[skip_serializing_none]
990#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
991#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
992#[serde(rename_all = "camelCase")]
993#[non_exhaustive]
994pub struct NesRenameCapabilities {
995 #[serde_as(deserialize_as = "DefaultOnError")]
1001 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1002 #[serde(default)]
1003 #[serde(rename = "_meta")]
1004 pub meta: Option<Meta>,
1005}
1006
1007impl NesRenameCapabilities {
1008 #[must_use]
1010 pub fn new() -> Self {
1011 Self::default()
1012 }
1013}
1014
1015#[serde_as]
1017#[skip_serializing_none]
1018#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1019#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1020#[serde(rename_all = "camelCase")]
1021#[non_exhaustive]
1022pub struct NesSearchAndReplaceCapabilities {
1023 #[serde_as(deserialize_as = "DefaultOnError")]
1029 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1030 #[serde(default)]
1031 #[serde(rename = "_meta")]
1032 pub meta: Option<Meta>,
1033}
1034
1035impl NesSearchAndReplaceCapabilities {
1036 #[must_use]
1038 pub fn new() -> Self {
1039 Self::default()
1040 }
1041}
1042
1043#[serde_as]
1047#[skip_serializing_none]
1048#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1049#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1050#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME)))]
1051#[serde(rename_all = "camelCase")]
1052#[non_exhaustive]
1053pub struct DidOpenDocumentNotification {
1054 pub session_id: SessionId,
1056 #[cfg_attr(feature = "schemars", schemars(url))]
1058 pub uri: String,
1059 pub language_id: String,
1061 pub version: i64,
1063 pub text: String,
1065 #[serde_as(deserialize_as = "DefaultOnError")]
1071 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1072 #[serde(default)]
1073 #[serde(rename = "_meta")]
1074 pub meta: Option<Meta>,
1075}
1076
1077impl DidOpenDocumentNotification {
1078 #[must_use]
1080 pub fn new(
1081 session_id: impl Into<SessionId>,
1082 uri: impl Into<String>,
1083 language_id: impl Into<String>,
1084 version: i64,
1085 text: impl Into<String>,
1086 ) -> Self {
1087 Self {
1088 session_id: session_id.into(),
1089 uri: uri.into(),
1090 language_id: language_id.into(),
1091 version,
1092 text: text.into(),
1093 meta: None,
1094 }
1095 }
1096
1097 #[must_use]
1103 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1104 self.meta = meta.into_option();
1105 self
1106 }
1107}
1108
1109#[serde_as]
1111#[skip_serializing_none]
1112#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1113#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1114#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME)))]
1115#[serde(rename_all = "camelCase")]
1116#[non_exhaustive]
1117pub struct DidChangeDocumentNotification {
1118 pub session_id: SessionId,
1120 #[cfg_attr(feature = "schemars", schemars(url))]
1122 pub uri: String,
1123 pub version: i64,
1125 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
1127 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true)))]
1128 pub content_changes: Vec<TextDocumentContentChangeEvent>,
1129 #[serde_as(deserialize_as = "DefaultOnError")]
1135 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1136 #[serde(default)]
1137 #[serde(rename = "_meta")]
1138 pub meta: Option<Meta>,
1139}
1140
1141impl DidChangeDocumentNotification {
1142 #[must_use]
1144 pub fn new(
1145 session_id: impl Into<SessionId>,
1146 uri: impl Into<String>,
1147 version: i64,
1148 content_changes: Vec<TextDocumentContentChangeEvent>,
1149 ) -> Self {
1150 Self {
1151 session_id: session_id.into(),
1152 uri: uri.into(),
1153 version,
1154 content_changes,
1155 meta: None,
1156 }
1157 }
1158
1159 #[must_use]
1165 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1166 self.meta = meta.into_option();
1167 self
1168 }
1169}
1170
1171#[serde_as]
1176#[skip_serializing_none]
1177#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1178#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1179#[serde(rename_all = "camelCase")]
1180#[non_exhaustive]
1181pub struct TextDocumentContentChangeEvent {
1182 #[serde(default)]
1184 pub range: Option<Range>,
1185 pub text: String,
1187 #[serde_as(deserialize_as = "DefaultOnError")]
1193 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1194 #[serde(default)]
1195 #[serde(rename = "_meta")]
1196 pub meta: Option<Meta>,
1197}
1198
1199impl TextDocumentContentChangeEvent {
1200 #[must_use]
1202 pub fn full(text: impl Into<String>) -> Self {
1203 Self {
1204 range: None,
1205 text: text.into(),
1206 meta: None,
1207 }
1208 }
1209
1210 #[must_use]
1212 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
1213 Self {
1214 range: Some(range),
1215 text: text.into(),
1216 meta: None,
1217 }
1218 }
1219
1220 #[must_use]
1226 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1227 self.meta = meta.into_option();
1228 self
1229 }
1230}
1231
1232#[serde_as]
1234#[skip_serializing_none]
1235#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1236#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1237#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME)))]
1238#[serde(rename_all = "camelCase")]
1239#[non_exhaustive]
1240pub struct DidCloseDocumentNotification {
1241 pub session_id: SessionId,
1243 #[cfg_attr(feature = "schemars", schemars(url))]
1245 pub uri: String,
1246 #[serde_as(deserialize_as = "DefaultOnError")]
1252 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1253 #[serde(default)]
1254 #[serde(rename = "_meta")]
1255 pub meta: Option<Meta>,
1256}
1257
1258impl DidCloseDocumentNotification {
1259 #[must_use]
1261 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1262 Self {
1263 session_id: session_id.into(),
1264 uri: uri.into(),
1265 meta: None,
1266 }
1267 }
1268
1269 #[must_use]
1275 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1276 self.meta = meta.into_option();
1277 self
1278 }
1279}
1280
1281#[serde_as]
1283#[skip_serializing_none]
1284#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1285#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1286#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_SAVE_METHOD_NAME)))]
1287#[serde(rename_all = "camelCase")]
1288#[non_exhaustive]
1289pub struct DidSaveDocumentNotification {
1290 pub session_id: SessionId,
1292 #[cfg_attr(feature = "schemars", schemars(url))]
1294 pub uri: String,
1295 #[serde_as(deserialize_as = "DefaultOnError")]
1301 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1302 #[serde(default)]
1303 #[serde(rename = "_meta")]
1304 pub meta: Option<Meta>,
1305}
1306
1307impl DidSaveDocumentNotification {
1308 #[must_use]
1310 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1311 Self {
1312 session_id: session_id.into(),
1313 uri: uri.into(),
1314 meta: None,
1315 }
1316 }
1317
1318 #[must_use]
1324 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1325 self.meta = meta.into_option();
1326 self
1327 }
1328}
1329
1330#[serde_as]
1332#[skip_serializing_none]
1333#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1334#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1335#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME)))]
1336#[serde(rename_all = "camelCase")]
1337#[non_exhaustive]
1338pub struct DidFocusDocumentNotification {
1339 pub session_id: SessionId,
1341 #[cfg_attr(feature = "schemars", schemars(url))]
1343 pub uri: String,
1344 pub version: i64,
1346 pub position: Position,
1348 pub visible_range: Range,
1350 #[serde_as(deserialize_as = "DefaultOnError")]
1356 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1357 #[serde(default)]
1358 #[serde(rename = "_meta")]
1359 pub meta: Option<Meta>,
1360}
1361
1362impl DidFocusDocumentNotification {
1363 #[must_use]
1365 pub fn new(
1366 session_id: impl Into<SessionId>,
1367 uri: impl Into<String>,
1368 version: i64,
1369 position: Position,
1370 visible_range: Range,
1371 ) -> Self {
1372 Self {
1373 session_id: session_id.into(),
1374 uri: uri.into(),
1375 version,
1376 position,
1377 visible_range,
1378 meta: None,
1379 }
1380 }
1381
1382 #[must_use]
1388 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1389 self.meta = meta.into_option();
1390 self
1391 }
1392}
1393
1394crate::serde_util::default_on_null! {
1397 #[serde_as]
1399 #[skip_serializing_none]
1400 #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1401 #[derive(Debug, Clone, Serialize, PartialEq, Eq)]
1402 #[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME)))]
1403 #[serde(rename_all = "camelCase")]
1404 #[non_exhaustive]
1405 pub struct StartNesRequest {
1406 #[serde_as(deserialize_as = "DefaultOnError")]
1408 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1409 #[cfg_attr(feature = "schemars", schemars(url))]
1410 #[serde(default)]
1411 pub workspace_uri: Option<String>,
1412 #[serde(default)]
1414 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1415 #[serde_as(deserialize_as = "DefaultOnError")]
1417 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1418 #[serde(default)]
1419 pub repository: Option<NesRepository>,
1420 #[serde_as(deserialize_as = "DefaultOnError")]
1426 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1427 #[serde(default)]
1428 #[serde(rename = "_meta")]
1429 pub meta: Option<Meta>,
1430 }
1431}
1432
1433impl StartNesRequest {
1434 #[must_use]
1436 pub fn new() -> Self {
1437 Self {
1438 workspace_uri: None,
1439 workspace_folders: None,
1440 repository: None,
1441 meta: None,
1442 }
1443 }
1444
1445 #[must_use]
1447 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1448 self.workspace_uri = workspace_uri.into_option();
1449 self
1450 }
1451
1452 #[must_use]
1454 pub fn workspace_folders(
1455 mut self,
1456 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1457 ) -> Self {
1458 self.workspace_folders = workspace_folders.into_option();
1459 self
1460 }
1461
1462 #[must_use]
1464 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1465 self.repository = repository.into_option();
1466 self
1467 }
1468
1469 #[must_use]
1475 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1476 self.meta = meta.into_option();
1477 self
1478 }
1479}
1480
1481impl Default for StartNesRequest {
1482 fn default() -> Self {
1483 Self::new()
1484 }
1485}
1486
1487#[serde_as]
1489#[skip_serializing_none]
1490#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1491#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1492#[serde(rename_all = "camelCase")]
1493#[non_exhaustive]
1494pub struct WorkspaceFolder {
1495 #[cfg_attr(feature = "schemars", schemars(url))]
1497 pub uri: String,
1498 pub name: String,
1500 #[serde_as(deserialize_as = "DefaultOnError")]
1506 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1507 #[serde(default)]
1508 #[serde(rename = "_meta")]
1509 pub meta: Option<Meta>,
1510}
1511
1512impl WorkspaceFolder {
1513 #[must_use]
1515 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1516 Self {
1517 uri: uri.into(),
1518 name: name.into(),
1519 meta: None,
1520 }
1521 }
1522
1523 #[must_use]
1529 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1530 self.meta = meta.into_option();
1531 self
1532 }
1533}
1534
1535#[serde_as]
1537#[skip_serializing_none]
1538#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1539#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1540#[serde(rename_all = "camelCase")]
1541#[non_exhaustive]
1542pub struct NesRepository {
1543 pub name: String,
1545 pub owner: String,
1547 pub remote_url: String,
1549 #[serde_as(deserialize_as = "DefaultOnError")]
1555 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1556 #[serde(default)]
1557 #[serde(rename = "_meta")]
1558 pub meta: Option<Meta>,
1559}
1560
1561impl NesRepository {
1562 #[must_use]
1564 pub fn new(
1565 name: impl Into<String>,
1566 owner: impl Into<String>,
1567 remote_url: impl Into<String>,
1568 ) -> Self {
1569 Self {
1570 name: name.into(),
1571 owner: owner.into(),
1572 remote_url: remote_url.into(),
1573 meta: None,
1574 }
1575 }
1576
1577 #[must_use]
1583 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1584 self.meta = meta.into_option();
1585 self
1586 }
1587}
1588
1589#[serde_as]
1591#[skip_serializing_none]
1592#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1593#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1594#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME)))]
1595#[serde(rename_all = "camelCase")]
1596#[non_exhaustive]
1597pub struct StartNesResponse {
1598 pub session_id: SessionId,
1600 #[serde_as(deserialize_as = "DefaultOnError")]
1606 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1607 #[serde(default)]
1608 #[serde(rename = "_meta")]
1609 pub meta: Option<Meta>,
1610}
1611
1612impl StartNesResponse {
1613 #[must_use]
1615 pub fn new(session_id: impl Into<SessionId>) -> Self {
1616 Self {
1617 session_id: session_id.into(),
1618 meta: None,
1619 }
1620 }
1621
1622 #[must_use]
1628 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1629 self.meta = meta.into_option();
1630 self
1631 }
1632}
1633
1634#[serde_as]
1641#[skip_serializing_none]
1642#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1643#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1644#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME)))]
1645#[serde(rename_all = "camelCase")]
1646#[non_exhaustive]
1647pub struct CloseNesRequest {
1648 pub session_id: SessionId,
1650 #[serde_as(deserialize_as = "DefaultOnError")]
1656 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1657 #[serde(default)]
1658 #[serde(rename = "_meta")]
1659 pub meta: Option<Meta>,
1660}
1661
1662impl CloseNesRequest {
1663 #[must_use]
1665 pub fn new(session_id: impl Into<SessionId>) -> Self {
1666 Self {
1667 session_id: session_id.into(),
1668 meta: None,
1669 }
1670 }
1671
1672 #[must_use]
1678 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1679 self.meta = meta.into_option();
1680 self
1681 }
1682}
1683
1684crate::serde_util::default_on_null! {
1685 #[serde_as]
1687 #[skip_serializing_none]
1688 #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1689 #[derive(Default, Debug, Clone, Serialize, PartialEq, Eq)]
1690 #[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME)))]
1691 #[serde(rename_all = "camelCase")]
1692 #[non_exhaustive]
1693 pub struct CloseNesResponse {
1694 #[serde_as(deserialize_as = "DefaultOnError")]
1700 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1701 #[serde(default)]
1702 #[serde(rename = "_meta")]
1703 pub meta: Option<Meta>,
1704 }
1705}
1706
1707impl CloseNesResponse {
1708 #[must_use]
1710 pub fn new() -> Self {
1711 Self::default()
1712 }
1713
1714 #[must_use]
1720 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1721 self.meta = meta.into_option();
1722 self
1723 }
1724}
1725
1726#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1730#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1731#[non_exhaustive]
1732pub enum NesTriggerKind {
1733 #[serde(rename = "automatic")]
1735 Automatic,
1736 #[serde(rename = "diagnostic")]
1738 Diagnostic,
1739 #[serde(rename = "manual")]
1741 Manual,
1742 #[serde(untagged)]
1748 Other(String),
1749}
1750
1751#[serde_as]
1753#[skip_serializing_none]
1754#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1755#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1756#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME)))]
1757#[serde(rename_all = "camelCase")]
1758#[non_exhaustive]
1759pub struct SuggestNesRequest {
1760 pub session_id: SessionId,
1762 #[cfg_attr(feature = "schemars", schemars(url))]
1764 pub uri: String,
1765 pub version: i64,
1767 pub position: Position,
1769 #[serde(default)]
1771 pub selection: Option<Range>,
1772 pub trigger_kind: NesTriggerKind,
1774 #[serde(default)]
1776 pub context: Option<NesSuggestContext>,
1777 #[serde_as(deserialize_as = "DefaultOnError")]
1783 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1784 #[serde(default)]
1785 #[serde(rename = "_meta")]
1786 pub meta: Option<Meta>,
1787}
1788
1789impl SuggestNesRequest {
1790 #[must_use]
1792 pub fn new(
1793 session_id: impl Into<SessionId>,
1794 uri: impl Into<String>,
1795 version: i64,
1796 position: Position,
1797 trigger_kind: NesTriggerKind,
1798 ) -> Self {
1799 Self {
1800 session_id: session_id.into(),
1801 uri: uri.into(),
1802 version,
1803 position,
1804 selection: None,
1805 trigger_kind,
1806 context: None,
1807 meta: None,
1808 }
1809 }
1810
1811 #[must_use]
1813 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1814 self.selection = selection.into_option();
1815 self
1816 }
1817
1818 #[must_use]
1820 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1821 self.context = context.into_option();
1822 self
1823 }
1824
1825 #[must_use]
1831 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1832 self.meta = meta.into_option();
1833 self
1834 }
1835}
1836
1837#[serde_as]
1839#[skip_serializing_none]
1840#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1841#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1842#[serde(rename_all = "camelCase")]
1843#[non_exhaustive]
1844pub struct NesSuggestContext {
1845 #[serde(default)]
1847 pub recent_files: Option<Vec<NesRecentFile>>,
1848 #[serde(default)]
1850 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1851 #[serde(default)]
1853 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1854 #[serde(default)]
1856 pub user_actions: Option<Vec<NesUserAction>>,
1857 #[serde(default)]
1859 pub open_files: Option<Vec<NesOpenFile>>,
1860 #[serde(default)]
1862 pub diagnostics: Option<Vec<NesDiagnostic>>,
1863 #[serde_as(deserialize_as = "DefaultOnError")]
1869 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1870 #[serde(default)]
1871 #[serde(rename = "_meta")]
1872 pub meta: Option<Meta>,
1873}
1874
1875impl NesSuggestContext {
1876 #[must_use]
1878 pub fn new() -> Self {
1879 Self::default()
1880 }
1881
1882 #[must_use]
1884 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1885 self.recent_files = recent_files.into_option();
1886 self
1887 }
1888
1889 #[must_use]
1891 pub fn related_snippets(
1892 mut self,
1893 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1894 ) -> Self {
1895 self.related_snippets = related_snippets.into_option();
1896 self
1897 }
1898
1899 #[must_use]
1901 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1902 self.edit_history = edit_history.into_option();
1903 self
1904 }
1905
1906 #[must_use]
1908 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1909 self.user_actions = user_actions.into_option();
1910 self
1911 }
1912
1913 #[must_use]
1915 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1916 self.open_files = open_files.into_option();
1917 self
1918 }
1919
1920 #[must_use]
1922 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1923 self.diagnostics = diagnostics.into_option();
1924 self
1925 }
1926
1927 #[must_use]
1933 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1934 self.meta = meta.into_option();
1935 self
1936 }
1937}
1938
1939#[serde_as]
1941#[skip_serializing_none]
1942#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1943#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1944#[serde(rename_all = "camelCase")]
1945#[non_exhaustive]
1946pub struct NesRecentFile {
1947 #[cfg_attr(feature = "schemars", schemars(url))]
1949 pub uri: String,
1950 pub language_id: String,
1952 pub text: String,
1954 #[serde_as(deserialize_as = "DefaultOnError")]
1960 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1961 #[serde(default)]
1962 #[serde(rename = "_meta")]
1963 pub meta: Option<Meta>,
1964}
1965
1966impl NesRecentFile {
1967 #[must_use]
1969 pub fn new(
1970 uri: impl Into<String>,
1971 language_id: impl Into<String>,
1972 text: impl Into<String>,
1973 ) -> Self {
1974 Self {
1975 uri: uri.into(),
1976 language_id: language_id.into(),
1977 text: text.into(),
1978 meta: None,
1979 }
1980 }
1981
1982 #[must_use]
1988 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1989 self.meta = meta.into_option();
1990 self
1991 }
1992}
1993
1994#[serde_as]
1996#[skip_serializing_none]
1997#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1998#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1999#[serde(rename_all = "camelCase")]
2000#[non_exhaustive]
2001pub struct NesRelatedSnippet {
2002 #[cfg_attr(feature = "schemars", schemars(url))]
2004 pub uri: String,
2005 pub excerpts: Vec<NesExcerpt>,
2007 #[serde_as(deserialize_as = "DefaultOnError")]
2013 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2014 #[serde(default)]
2015 #[serde(rename = "_meta")]
2016 pub meta: Option<Meta>,
2017}
2018
2019impl NesRelatedSnippet {
2020 #[must_use]
2022 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
2023 Self {
2024 uri: uri.into(),
2025 excerpts,
2026 meta: None,
2027 }
2028 }
2029
2030 #[must_use]
2036 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2037 self.meta = meta.into_option();
2038 self
2039 }
2040}
2041
2042#[serde_as]
2044#[skip_serializing_none]
2045#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2046#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2047#[serde(rename_all = "camelCase")]
2048#[non_exhaustive]
2049pub struct NesExcerpt {
2050 pub start_line: u32,
2052 pub end_line: u32,
2054 pub text: String,
2056 #[serde_as(deserialize_as = "DefaultOnError")]
2062 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2063 #[serde(default)]
2064 #[serde(rename = "_meta")]
2065 pub meta: Option<Meta>,
2066}
2067
2068impl NesExcerpt {
2069 #[must_use]
2071 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
2072 Self {
2073 start_line,
2074 end_line,
2075 text: text.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#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2096#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2097#[serde(rename_all = "camelCase")]
2098#[non_exhaustive]
2099pub struct NesEditHistoryEntry {
2100 #[cfg_attr(feature = "schemars", schemars(url))]
2102 pub uri: String,
2103 pub diff: String,
2105 #[serde_as(deserialize_as = "DefaultOnError")]
2111 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2112 #[serde(default)]
2113 #[serde(rename = "_meta")]
2114 pub meta: Option<Meta>,
2115}
2116
2117impl NesEditHistoryEntry {
2118 #[must_use]
2120 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
2121 Self {
2122 uri: uri.into(),
2123 diff: diff.into(),
2124 meta: None,
2125 }
2126 }
2127
2128 #[must_use]
2134 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2135 self.meta = meta.into_option();
2136 self
2137 }
2138}
2139
2140#[serde_as]
2142#[skip_serializing_none]
2143#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2144#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2145#[serde(rename_all = "camelCase")]
2146#[non_exhaustive]
2147pub struct NesUserAction {
2148 pub action: String,
2150 #[cfg_attr(feature = "schemars", schemars(url))]
2152 pub uri: String,
2153 pub position: Position,
2155 pub timestamp_ms: u64,
2157 #[serde_as(deserialize_as = "DefaultOnError")]
2163 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2164 #[serde(default)]
2165 #[serde(rename = "_meta")]
2166 pub meta: Option<Meta>,
2167}
2168
2169impl NesUserAction {
2170 #[must_use]
2172 pub fn new(
2173 action: impl Into<String>,
2174 uri: impl Into<String>,
2175 position: Position,
2176 timestamp_ms: u64,
2177 ) -> Self {
2178 Self {
2179 action: action.into(),
2180 uri: uri.into(),
2181 position,
2182 timestamp_ms,
2183 meta: None,
2184 }
2185 }
2186
2187 #[must_use]
2193 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2194 self.meta = meta.into_option();
2195 self
2196 }
2197}
2198
2199#[serde_as]
2201#[skip_serializing_none]
2202#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2203#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2204#[serde(rename_all = "camelCase")]
2205#[non_exhaustive]
2206pub struct NesOpenFile {
2207 #[cfg_attr(feature = "schemars", schemars(url))]
2209 pub uri: String,
2210 pub language_id: String,
2212 #[serde_as(deserialize_as = "DefaultOnError")]
2214 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2215 #[serde(default)]
2216 pub visible_range: Option<Range>,
2217 #[serde_as(deserialize_as = "DefaultOnError")]
2219 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2220 #[serde(default)]
2221 pub last_focused_ms: Option<u64>,
2222 #[serde_as(deserialize_as = "DefaultOnError")]
2228 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2229 #[serde(default)]
2230 #[serde(rename = "_meta")]
2231 pub meta: Option<Meta>,
2232}
2233
2234impl NesOpenFile {
2235 #[must_use]
2237 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
2238 Self {
2239 uri: uri.into(),
2240 language_id: language_id.into(),
2241 visible_range: None,
2242 last_focused_ms: None,
2243 meta: None,
2244 }
2245 }
2246
2247 #[must_use]
2249 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
2250 self.visible_range = visible_range.into_option();
2251 self
2252 }
2253
2254 #[must_use]
2256 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
2257 self.last_focused_ms = last_focused_ms.into_option();
2258 self
2259 }
2260
2261 #[must_use]
2267 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2268 self.meta = meta.into_option();
2269 self
2270 }
2271}
2272
2273#[serde_as]
2275#[skip_serializing_none]
2276#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2277#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2278#[serde(rename_all = "camelCase")]
2279#[non_exhaustive]
2280pub struct NesDiagnostic {
2281 #[cfg_attr(feature = "schemars", schemars(url))]
2283 pub uri: String,
2284 pub range: Range,
2286 pub severity: NesDiagnosticSeverity,
2288 pub message: String,
2290 #[serde_as(deserialize_as = "DefaultOnError")]
2296 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2297 #[serde(default)]
2298 #[serde(rename = "_meta")]
2299 pub meta: Option<Meta>,
2300}
2301
2302impl NesDiagnostic {
2303 #[must_use]
2305 pub fn new(
2306 uri: impl Into<String>,
2307 range: Range,
2308 severity: NesDiagnosticSeverity,
2309 message: impl Into<String>,
2310 ) -> Self {
2311 Self {
2312 uri: uri.into(),
2313 range,
2314 severity,
2315 message: message.into(),
2316 meta: None,
2317 }
2318 }
2319
2320 #[must_use]
2326 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2327 self.meta = meta.into_option();
2328 self
2329 }
2330}
2331
2332#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2334#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2335#[non_exhaustive]
2336pub enum NesDiagnosticSeverity {
2337 #[serde(rename = "error")]
2339 Error,
2340 #[serde(rename = "warning")]
2342 Warning,
2343 #[serde(rename = "information")]
2345 Information,
2346 #[serde(rename = "hint")]
2348 Hint,
2349 #[serde(untagged)]
2355 Other(String),
2356}
2357
2358#[serde_as]
2362#[skip_serializing_none]
2363#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2364#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2365#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME)))]
2366#[serde(rename_all = "camelCase")]
2367#[non_exhaustive]
2368pub struct SuggestNesResponse {
2369 pub suggestions: Vec<NesSuggestion>,
2371 #[serde_as(deserialize_as = "DefaultOnError")]
2377 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2378 #[serde(default)]
2379 #[serde(rename = "_meta")]
2380 pub meta: Option<Meta>,
2381}
2382
2383impl SuggestNesResponse {
2384 #[must_use]
2386 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2387 Self {
2388 suggestions,
2389 meta: None,
2390 }
2391 }
2392
2393 #[must_use]
2399 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2400 self.meta = meta.into_option();
2401 self
2402 }
2403}
2404
2405#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2407#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2408#[serde(tag = "kind", rename_all = "camelCase")]
2409#[non_exhaustive]
2410pub enum NesSuggestion {
2411 Edit(NesEditSuggestion),
2413 Jump(NesJumpSuggestion),
2415 Rename(NesRenameSuggestion),
2417 SearchAndReplace(NesSearchAndReplaceSuggestion),
2419 #[serde(untagged)]
2429 Other(OtherNesSuggestion),
2430}
2431
2432#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2434#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
2435#[cfg_attr(feature = "schemars", schemars(inline))]
2436#[cfg_attr(feature = "schemars", schemars(transform = other_nes_suggestion_schema))]
2437#[serde(rename_all = "camelCase")]
2438#[non_exhaustive]
2439pub struct OtherNesSuggestion {
2440 pub kind: String,
2446 pub suggestion_id: NesSuggestionId,
2448 #[serde(flatten)]
2450 pub fields: BTreeMap<String, serde_json::Value>,
2451}
2452
2453impl OtherNesSuggestion {
2454 #[must_use]
2456 pub fn new(
2457 kind: impl Into<String>,
2458 suggestion_id: impl Into<NesSuggestionId>,
2459 mut fields: BTreeMap<String, serde_json::Value>,
2460 ) -> Self {
2461 fields.remove("kind");
2462 fields.remove("suggestionId");
2463 Self {
2464 kind: kind.into(),
2465 suggestion_id: suggestion_id.into(),
2466 fields,
2467 }
2468 }
2469}
2470
2471impl<'de> Deserialize<'de> for OtherNesSuggestion {
2472 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2473 where
2474 D: serde::Deserializer<'de>,
2475 {
2476 let mut fields = BTreeMap::<String, serde_json::Value>::deserialize(deserializer)?;
2477 let kind = fields
2478 .remove("kind")
2479 .ok_or_else(|| serde::de::Error::missing_field("kind"))?;
2480 let serde_json::Value::String(kind) = kind else {
2481 return Err(serde::de::Error::custom("`kind` must be a string"));
2482 };
2483 let suggestion_id = fields
2484 .remove("suggestionId")
2485 .ok_or_else(|| serde::de::Error::missing_field("suggestionId"))?;
2486 let serde_json::Value::String(suggestion_id) = suggestion_id else {
2487 return Err(serde::de::Error::custom("`suggestionId` must be a string"));
2488 };
2489
2490 if is_known_nes_suggestion_kind(&kind) {
2491 return Err(serde::de::Error::custom(format!(
2492 "known NES suggestion `{kind}` did not match its schema"
2493 )));
2494 }
2495
2496 Ok(Self {
2497 kind,
2498 suggestion_id: NesSuggestionId::new(suggestion_id),
2499 fields,
2500 })
2501 }
2502}
2503
2504fn is_known_nes_suggestion_kind(kind: &str) -> bool {
2505 matches!(kind, "edit" | "jump" | "rename" | "searchAndReplace")
2506}
2507
2508#[cfg(feature = "schemars")]
2509fn other_nes_suggestion_schema(schema: &mut Schema) {
2510 super::schema_util::reject_known_string_discriminators(
2511 schema,
2512 "kind",
2513 &["edit", "jump", "rename", "searchAndReplace"],
2514 );
2515}
2516
2517#[serde_as]
2519#[skip_serializing_none]
2520#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2521#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2522#[serde(rename_all = "camelCase")]
2523#[non_exhaustive]
2524pub struct NesEditSuggestion {
2525 pub suggestion_id: NesSuggestionId,
2527 #[cfg_attr(feature = "schemars", schemars(url))]
2529 pub uri: String,
2530 #[cfg_attr(feature = "schemars", schemars(length(min = 1)))]
2532 pub edits: Vec<NesTextEdit>,
2533 #[serde_as(deserialize_as = "DefaultOnError")]
2535 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2536 #[serde(default)]
2537 pub cursor_position: Option<Position>,
2538 #[serde_as(deserialize_as = "DefaultOnError")]
2544 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2545 #[serde(default)]
2546 #[serde(rename = "_meta")]
2547 pub meta: Option<Meta>,
2548}
2549
2550impl NesEditSuggestion {
2551 #[must_use]
2553 pub fn new(
2554 suggestion_id: impl Into<NesSuggestionId>,
2555 uri: impl Into<String>,
2556 edits: Vec<NesTextEdit>,
2557 ) -> Self {
2558 Self {
2559 suggestion_id: suggestion_id.into(),
2560 uri: uri.into(),
2561 edits,
2562 cursor_position: None,
2563 meta: None,
2564 }
2565 }
2566
2567 #[must_use]
2569 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2570 self.cursor_position = cursor_position.into_option();
2571 self
2572 }
2573
2574 #[must_use]
2580 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2581 self.meta = meta.into_option();
2582 self
2583 }
2584}
2585
2586#[serde_as]
2588#[skip_serializing_none]
2589#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2590#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2591#[serde(rename_all = "camelCase")]
2592#[non_exhaustive]
2593pub struct NesTextEdit {
2594 pub range: Range,
2596 pub new_text: String,
2598 #[serde_as(deserialize_as = "DefaultOnError")]
2604 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2605 #[serde(default)]
2606 #[serde(rename = "_meta")]
2607 pub meta: Option<Meta>,
2608}
2609
2610impl NesTextEdit {
2611 #[must_use]
2613 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2614 Self {
2615 range,
2616 new_text: new_text.into(),
2617 meta: None,
2618 }
2619 }
2620
2621 #[must_use]
2627 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2628 self.meta = meta.into_option();
2629 self
2630 }
2631}
2632
2633#[serde_as]
2635#[skip_serializing_none]
2636#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2637#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2638#[serde(rename_all = "camelCase")]
2639#[non_exhaustive]
2640pub struct NesJumpSuggestion {
2641 pub suggestion_id: NesSuggestionId,
2643 #[cfg_attr(feature = "schemars", schemars(url))]
2645 pub uri: String,
2646 pub position: Position,
2648 #[serde_as(deserialize_as = "DefaultOnError")]
2654 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2655 #[serde(default)]
2656 #[serde(rename = "_meta")]
2657 pub meta: Option<Meta>,
2658}
2659
2660impl NesJumpSuggestion {
2661 #[must_use]
2663 pub fn new(
2664 suggestion_id: impl Into<NesSuggestionId>,
2665 uri: impl Into<String>,
2666 position: Position,
2667 ) -> Self {
2668 Self {
2669 suggestion_id: suggestion_id.into(),
2670 uri: uri.into(),
2671 position,
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#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2692#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2693#[serde(rename_all = "camelCase")]
2694#[non_exhaustive]
2695pub struct NesRenameSuggestion {
2696 pub suggestion_id: NesSuggestionId,
2698 #[cfg_attr(feature = "schemars", schemars(url))]
2700 pub uri: String,
2701 pub position: Position,
2703 pub new_name: String,
2705 #[serde_as(deserialize_as = "DefaultOnError")]
2711 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2712 #[serde(default)]
2713 #[serde(rename = "_meta")]
2714 pub meta: Option<Meta>,
2715}
2716
2717impl NesRenameSuggestion {
2718 #[must_use]
2720 pub fn new(
2721 suggestion_id: impl Into<NesSuggestionId>,
2722 uri: impl Into<String>,
2723 position: Position,
2724 new_name: impl Into<String>,
2725 ) -> Self {
2726 Self {
2727 suggestion_id: suggestion_id.into(),
2728 uri: uri.into(),
2729 position,
2730 new_name: new_name.into(),
2731 meta: None,
2732 }
2733 }
2734
2735 #[must_use]
2741 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2742 self.meta = meta.into_option();
2743 self
2744 }
2745}
2746
2747#[serde_as]
2749#[skip_serializing_none]
2750#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2751#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2752#[serde(rename_all = "camelCase")]
2753#[non_exhaustive]
2754pub struct NesSearchAndReplaceSuggestion {
2755 pub suggestion_id: NesSuggestionId,
2757 #[cfg_attr(feature = "schemars", schemars(url))]
2759 pub uri: String,
2760 pub search: String,
2762 pub replace: String,
2764 #[serde(default)]
2766 pub is_regex: Option<bool>,
2767 #[serde_as(deserialize_as = "DefaultOnError")]
2773 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2774 #[serde(default)]
2775 #[serde(rename = "_meta")]
2776 pub meta: Option<Meta>,
2777}
2778
2779impl NesSearchAndReplaceSuggestion {
2780 #[must_use]
2782 pub fn new(
2783 suggestion_id: impl Into<NesSuggestionId>,
2784 uri: impl Into<String>,
2785 search: impl Into<String>,
2786 replace: impl Into<String>,
2787 ) -> Self {
2788 Self {
2789 suggestion_id: suggestion_id.into(),
2790 uri: uri.into(),
2791 search: search.into(),
2792 replace: replace.into(),
2793 is_regex: None,
2794 meta: None,
2795 }
2796 }
2797
2798 #[must_use]
2800 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2801 self.is_regex = is_regex.into_option();
2802 self
2803 }
2804
2805 #[must_use]
2811 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2812 self.meta = meta.into_option();
2813 self
2814 }
2815}
2816
2817#[serde_as]
2821#[skip_serializing_none]
2822#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2823#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2824#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME)))]
2825#[serde(rename_all = "camelCase")]
2826#[non_exhaustive]
2827pub struct AcceptNesNotification {
2828 pub session_id: SessionId,
2830 pub suggestion_id: NesSuggestionId,
2832 #[serde_as(deserialize_as = "DefaultOnError")]
2838 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2839 #[serde(default)]
2840 #[serde(rename = "_meta")]
2841 pub meta: Option<Meta>,
2842}
2843
2844impl AcceptNesNotification {
2845 #[must_use]
2847 pub fn new(
2848 session_id: impl Into<SessionId>,
2849 suggestion_id: impl Into<NesSuggestionId>,
2850 ) -> Self {
2851 Self {
2852 session_id: session_id.into(),
2853 suggestion_id: suggestion_id.into(),
2854 meta: None,
2855 }
2856 }
2857
2858 #[must_use]
2864 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2865 self.meta = meta.into_option();
2866 self
2867 }
2868}
2869
2870#[serde_as]
2872#[skip_serializing_none]
2873#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2874#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2875#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME)))]
2876#[serde(rename_all = "camelCase")]
2877#[non_exhaustive]
2878pub struct RejectNesNotification {
2879 pub session_id: SessionId,
2881 pub suggestion_id: NesSuggestionId,
2883 #[serde_as(deserialize_as = "DefaultOnError")]
2885 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2886 #[serde(default)]
2887 pub reason: Option<NesRejectReason>,
2888 #[serde_as(deserialize_as = "DefaultOnError")]
2894 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2895 #[serde(default)]
2896 #[serde(rename = "_meta")]
2897 pub meta: Option<Meta>,
2898}
2899
2900impl RejectNesNotification {
2901 #[must_use]
2903 pub fn new(
2904 session_id: impl Into<SessionId>,
2905 suggestion_id: impl Into<NesSuggestionId>,
2906 ) -> Self {
2907 Self {
2908 session_id: session_id.into(),
2909 suggestion_id: suggestion_id.into(),
2910 reason: None,
2911 meta: None,
2912 }
2913 }
2914
2915 #[must_use]
2917 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2918 self.reason = reason.into_option();
2919 self
2920 }
2921
2922 #[must_use]
2928 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2929 self.meta = meta.into_option();
2930 self
2931 }
2932}
2933
2934#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2936#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2937#[non_exhaustive]
2938pub enum NesRejectReason {
2939 #[serde(rename = "rejected")]
2941 Rejected,
2942 #[serde(rename = "ignored")]
2944 Ignored,
2945 #[serde(rename = "replaced")]
2947 Replaced,
2948 #[serde(rename = "cancelled")]
2950 Cancelled,
2951 #[serde(untagged)]
2957 Other(String),
2958}
2959
2960#[cfg(test)]
2961mod tests {
2962 use super::*;
2963 use serde_json::json;
2964
2965 #[test]
2966 fn test_position_encoding_kind_serialization() {
2967 assert_eq!(
2968 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2969 json!("utf-16")
2970 );
2971 assert_eq!(
2972 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2973 json!("utf-32")
2974 );
2975 assert_eq!(
2976 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2977 json!("utf-8")
2978 );
2979
2980 assert_eq!(
2981 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2982 PositionEncodingKind::Utf16
2983 );
2984 assert_eq!(
2985 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2986 PositionEncodingKind::Utf32
2987 );
2988 assert_eq!(
2989 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2990 PositionEncodingKind::Utf8
2991 );
2992 assert!(serde_json::from_value::<PositionEncodingKind>(json!("_future")).is_err());
2993 }
2994
2995 #[test]
2996 fn test_client_capabilities_skip_unknown_position_encodings() {
2997 let caps: crate::v2::ClientCapabilities = serde_json::from_value(json!({
2998 "positionEncodings": ["_future", "utf-8", "utf-16"]
2999 }))
3000 .unwrap();
3001
3002 assert_eq!(
3003 caps.position_encodings,
3004 vec![PositionEncodingKind::Utf8, PositionEncodingKind::Utf16]
3005 );
3006 }
3007
3008 #[test]
3009 fn test_agent_nes_capabilities_serialization() {
3010 let caps = NesCapabilities::new()
3011 .events(
3012 NesEventCapabilities::new().document(
3013 NesDocumentEventCapabilities::new()
3014 .did_open(NesDocumentDidOpenCapabilities::default())
3015 .did_change(NesDocumentDidChangeCapabilities::new(
3016 TextDocumentSyncKind::Incremental,
3017 ))
3018 .did_close(NesDocumentDidCloseCapabilities::default())
3019 .did_save(NesDocumentDidSaveCapabilities::default())
3020 .did_focus(NesDocumentDidFocusCapabilities::default()),
3021 ),
3022 )
3023 .context(
3024 NesContextCapabilities::new()
3025 .recent_files(NesRecentFilesCapabilities {
3026 max_count: Some(10),
3027 meta: None,
3028 })
3029 .related_snippets(NesRelatedSnippetsCapabilities::default())
3030 .edit_history(NesEditHistoryCapabilities {
3031 max_count: Some(6),
3032 meta: None,
3033 })
3034 .user_actions(NesUserActionsCapabilities {
3035 max_count: Some(16),
3036 meta: None,
3037 })
3038 .open_files(NesOpenFilesCapabilities::default())
3039 .diagnostics(NesDiagnosticsCapabilities::default()),
3040 );
3041
3042 let json = serde_json::to_value(&caps).unwrap();
3043 assert_eq!(
3044 json,
3045 json!({
3046 "events": {
3047 "document": {
3048 "didOpen": {},
3049 "didChange": {
3050 "syncKind": "incremental"
3051 },
3052 "didClose": {},
3053 "didSave": {},
3054 "didFocus": {}
3055 }
3056 },
3057 "context": {
3058 "recentFiles": {
3059 "maxCount": 10
3060 },
3061 "relatedSnippets": {},
3062 "editHistory": {
3063 "maxCount": 6
3064 },
3065 "userActions": {
3066 "maxCount": 16
3067 },
3068 "openFiles": {},
3069 "diagnostics": {}
3070 }
3071 })
3072 );
3073
3074 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
3076 assert_eq!(deserialized, caps);
3077 }
3078
3079 #[test]
3080 fn test_client_nes_capabilities_serialization() {
3081 let caps = ClientNesCapabilities::new()
3082 .jump(NesJumpCapabilities::default())
3083 .rename(NesRenameCapabilities::default())
3084 .search_and_replace(NesSearchAndReplaceCapabilities::default());
3085
3086 let json = serde_json::to_value(&caps).unwrap();
3087 assert_eq!(
3088 json,
3089 json!({
3090 "jump": {},
3091 "rename": {},
3092 "searchAndReplace": {}
3093 })
3094 );
3095
3096 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
3097 assert_eq!(deserialized, caps);
3098 }
3099
3100 #[test]
3101 fn test_document_did_open_serialization() {
3102 let notification = DidOpenDocumentNotification::new(
3103 "session_123",
3104 "file:///path/to/file.rs",
3105 "rust",
3106 1,
3107 "fn main() {\n println!(\"hello\");\n}\n",
3108 );
3109
3110 let json = serde_json::to_value(¬ification).unwrap();
3111 assert_eq!(
3112 json,
3113 json!({
3114 "sessionId": "session_123",
3115 "uri": "file:///path/to/file.rs",
3116 "languageId": "rust",
3117 "version": 1,
3118 "text": "fn main() {\n println!(\"hello\");\n}\n"
3119 })
3120 );
3121
3122 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
3123 assert_eq!(deserialized, notification);
3124 }
3125
3126 #[test]
3127 fn test_document_did_change_incremental_serialization() {
3128 let notification = DidChangeDocumentNotification::new(
3129 "session_123",
3130 "file:///path/to/file.rs",
3131 2,
3132 vec![TextDocumentContentChangeEvent::incremental(
3133 Range::new(Position::new(1, 4), Position::new(1, 4)),
3134 "let x = 42;\n ",
3135 )],
3136 );
3137
3138 let json = serde_json::to_value(¬ification).unwrap();
3139 assert_eq!(
3140 json,
3141 json!({
3142 "sessionId": "session_123",
3143 "uri": "file:///path/to/file.rs",
3144 "version": 2,
3145 "contentChanges": [
3146 {
3147 "range": {
3148 "start": { "line": 1, "character": 4 },
3149 "end": { "line": 1, "character": 4 }
3150 },
3151 "text": "let x = 42;\n "
3152 }
3153 ]
3154 })
3155 );
3156 }
3157
3158 #[test]
3159 fn test_document_did_change_full_serialization() {
3160 let notification = DidChangeDocumentNotification::new(
3161 "session_123",
3162 "file:///path/to/file.rs",
3163 2,
3164 vec![TextDocumentContentChangeEvent::full(
3165 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
3166 )],
3167 );
3168
3169 let json = serde_json::to_value(¬ification).unwrap();
3170 assert_eq!(
3171 json,
3172 json!({
3173 "sessionId": "session_123",
3174 "uri": "file:///path/to/file.rs",
3175 "version": 2,
3176 "contentChanges": [
3177 {
3178 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
3179 }
3180 ]
3181 })
3182 );
3183 }
3184
3185 #[test]
3186 fn test_document_did_close_serialization() {
3187 let notification =
3188 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
3189 let json = serde_json::to_value(¬ification).unwrap();
3190 assert_eq!(
3191 json,
3192 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3193 );
3194 }
3195
3196 #[test]
3197 fn test_document_did_save_serialization() {
3198 let notification =
3199 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
3200 let json = serde_json::to_value(¬ification).unwrap();
3201 assert_eq!(
3202 json,
3203 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3204 );
3205 }
3206
3207 #[test]
3208 fn test_document_did_focus_serialization() {
3209 let notification = DidFocusDocumentNotification::new(
3210 "session_123",
3211 "file:///path/to/file.rs",
3212 2,
3213 Position::new(5, 12),
3214 Range::new(Position::new(0, 0), Position::new(45, 0)),
3215 );
3216
3217 let json = serde_json::to_value(¬ification).unwrap();
3218 assert_eq!(
3219 json,
3220 json!({
3221 "sessionId": "session_123",
3222 "uri": "file:///path/to/file.rs",
3223 "version": 2,
3224 "position": { "line": 5, "character": 12 },
3225 "visibleRange": {
3226 "start": { "line": 0, "character": 0 },
3227 "end": { "line": 45, "character": 0 }
3228 }
3229 })
3230 );
3231 }
3232
3233 #[test]
3234 fn test_nes_suggestion_edit_serialization() {
3235 let suggestion = NesSuggestion::Edit(
3236 NesEditSuggestion::new(
3237 "sugg_001",
3238 "file:///path/to/other_file.rs",
3239 vec![NesTextEdit::new(
3240 Range::new(Position::new(5, 0), Position::new(5, 10)),
3241 "let result = helper();",
3242 )],
3243 )
3244 .cursor_position(Position::new(5, 22)),
3245 );
3246
3247 let json = serde_json::to_value(&suggestion).unwrap();
3248 assert_eq!(
3249 json,
3250 json!({
3251 "kind": "edit",
3252 "suggestionId": "sugg_001",
3253 "uri": "file:///path/to/other_file.rs",
3254 "edits": [
3255 {
3256 "range": {
3257 "start": { "line": 5, "character": 0 },
3258 "end": { "line": 5, "character": 10 }
3259 },
3260 "newText": "let result = helper();"
3261 }
3262 ],
3263 "cursorPosition": { "line": 5, "character": 22 }
3264 })
3265 );
3266
3267 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3268 assert_eq!(deserialized, suggestion);
3269 }
3270
3271 #[test]
3272 fn test_nes_suggestion_unknown_variant() {
3273 let suggestion: NesSuggestion = serde_json::from_value(json!({
3274 "kind": "_preview",
3275 "suggestionId": "sugg_001",
3276 "label": "Preview generated file"
3277 }))
3278 .unwrap();
3279
3280 let NesSuggestion::Other(unknown) = suggestion else {
3281 panic!("expected unknown NES suggestion");
3282 };
3283
3284 assert_eq!(unknown.kind, "_preview");
3285 assert_eq!(unknown.suggestion_id.to_string(), "sugg_001");
3286 assert!(!unknown.fields.contains_key("suggestionId"));
3287 assert_eq!(
3288 serde_json::to_value(NesSuggestion::Other(unknown)).unwrap(),
3289 json!({
3290 "kind": "_preview",
3291 "suggestionId": "sugg_001",
3292 "label": "Preview generated file"
3293 })
3294 );
3295 }
3296
3297 #[test]
3298 fn test_nes_suggestion_unknown_does_not_hide_malformed_known_variant() {
3299 assert!(
3300 serde_json::from_value::<NesSuggestion>(json!({
3301 "kind": "edit"
3302 }))
3303 .is_err()
3304 );
3305 }
3306
3307 #[test]
3308 fn test_nes_suggestion_jump_serialization() {
3309 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
3310 "sugg_002",
3311 "file:///path/to/other_file.rs",
3312 Position::new(15, 4),
3313 ));
3314
3315 let json = serde_json::to_value(&suggestion).unwrap();
3316 assert_eq!(
3317 json,
3318 json!({
3319 "kind": "jump",
3320 "suggestionId": "sugg_002",
3321 "uri": "file:///path/to/other_file.rs",
3322 "position": { "line": 15, "character": 4 }
3323 })
3324 );
3325
3326 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3327 assert_eq!(deserialized, suggestion);
3328 }
3329
3330 #[test]
3331 fn test_nes_suggestion_rename_serialization() {
3332 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
3333 "sugg_003",
3334 "file:///path/to/file.rs",
3335 Position::new(5, 10),
3336 "calculateTotal",
3337 ));
3338
3339 let json = serde_json::to_value(&suggestion).unwrap();
3340 assert_eq!(
3341 json,
3342 json!({
3343 "kind": "rename",
3344 "suggestionId": "sugg_003",
3345 "uri": "file:///path/to/file.rs",
3346 "position": { "line": 5, "character": 10 },
3347 "newName": "calculateTotal"
3348 })
3349 );
3350
3351 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3352 assert_eq!(deserialized, suggestion);
3353 }
3354
3355 #[test]
3356 fn test_nes_suggestion_search_and_replace_serialization() {
3357 let suggestion = NesSuggestion::SearchAndReplace(
3358 NesSearchAndReplaceSuggestion::new(
3359 "sugg_004",
3360 "file:///path/to/file.rs",
3361 "oldFunction",
3362 "newFunction",
3363 )
3364 .is_regex(false),
3365 );
3366
3367 let json = serde_json::to_value(&suggestion).unwrap();
3368 assert_eq!(
3369 json,
3370 json!({
3371 "kind": "searchAndReplace",
3372 "suggestionId": "sugg_004",
3373 "uri": "file:///path/to/file.rs",
3374 "search": "oldFunction",
3375 "replace": "newFunction",
3376 "isRegex": false
3377 })
3378 );
3379
3380 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3381 assert_eq!(deserialized, suggestion);
3382 }
3383
3384 #[test]
3385 fn test_nes_start_request_serialization() {
3386 let request = StartNesRequest::new()
3387 .workspace_uri("file:///Users/alice/projects/my-app")
3388 .workspace_folders(vec![WorkspaceFolder::new(
3389 "file:///Users/alice/projects/my-app",
3390 "my-app",
3391 )])
3392 .repository(NesRepository::new(
3393 "my-app",
3394 "alice",
3395 "https://github.com/alice/my-app.git",
3396 ));
3397
3398 let json = serde_json::to_value(&request).unwrap();
3399 assert_eq!(
3400 json,
3401 json!({
3402 "workspaceUri": "file:///Users/alice/projects/my-app",
3403 "workspaceFolders": [
3404 {
3405 "uri": "file:///Users/alice/projects/my-app",
3406 "name": "my-app"
3407 }
3408 ],
3409 "repository": {
3410 "name": "my-app",
3411 "owner": "alice",
3412 "remoteUrl": "https://github.com/alice/my-app.git"
3413 }
3414 })
3415 );
3416 }
3417
3418 #[test]
3419 fn test_nes_start_response_serialization() {
3420 let response = StartNesResponse::new("session_abc123");
3421 let json = serde_json::to_value(&response).unwrap();
3422 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
3423 }
3424
3425 #[test]
3426 fn test_nes_trigger_kind_serialization() {
3427 assert_eq!(
3428 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
3429 json!("automatic")
3430 );
3431 assert_eq!(
3432 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
3433 json!("diagnostic")
3434 );
3435 assert_eq!(
3436 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
3437 json!("manual")
3438 );
3439 }
3440
3441 #[test]
3442 fn test_nes_reject_reason_serialization() {
3443 assert_eq!(
3444 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
3445 json!("rejected")
3446 );
3447 assert_eq!(
3448 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
3449 json!("ignored")
3450 );
3451 assert_eq!(
3452 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
3453 json!("replaced")
3454 );
3455 assert_eq!(
3456 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
3457 json!("cancelled")
3458 );
3459 }
3460
3461 #[test]
3462 fn test_nes_accept_notification_serialization() {
3463 let notification = AcceptNesNotification::new("session_123", "sugg_001");
3464 let json = serde_json::to_value(¬ification).unwrap();
3465 assert_eq!(
3466 json,
3467 json!({ "sessionId": "session_123", "suggestionId": "sugg_001" })
3468 );
3469 }
3470
3471 #[test]
3472 fn test_nes_reject_notification_serialization() {
3473 let notification =
3474 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
3475 let json = serde_json::to_value(¬ification).unwrap();
3476 assert_eq!(
3477 json,
3478 json!({ "sessionId": "session_123", "suggestionId": "sugg_001", "reason": "rejected" })
3479 );
3480 }
3481
3482 #[test]
3483 fn test_nes_suggest_request_with_context_serialization() {
3484 let request = SuggestNesRequest::new(
3485 "session_123",
3486 "file:///path/to/file.rs",
3487 2,
3488 Position::new(5, 12),
3489 NesTriggerKind::Automatic,
3490 )
3491 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
3492 .context(
3493 NesSuggestContext::new()
3494 .recent_files(vec![NesRecentFile::new(
3495 "file:///path/to/utils.rs",
3496 "rust",
3497 "pub fn helper() -> i32 { 42 }\n",
3498 )])
3499 .diagnostics(vec![NesDiagnostic::new(
3500 "file:///path/to/file.rs",
3501 Range::new(Position::new(5, 0), Position::new(5, 10)),
3502 NesDiagnosticSeverity::Error,
3503 "cannot find value `foo` in this scope",
3504 )]),
3505 );
3506
3507 let json = serde_json::to_value(&request).unwrap();
3508 assert_eq!(json["sessionId"], "session_123");
3509 assert_eq!(json["uri"], "file:///path/to/file.rs");
3510 assert_eq!(json["version"], 2);
3511 assert_eq!(json["triggerKind"], "automatic");
3512 assert_eq!(
3513 json["context"]["recentFiles"][0]["uri"],
3514 "file:///path/to/utils.rs"
3515 );
3516 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
3517 }
3518
3519 #[test]
3520 fn test_text_document_sync_kind_serialization() {
3521 assert_eq!(
3522 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
3523 json!("full")
3524 );
3525 assert_eq!(
3526 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
3527 json!("incremental")
3528 );
3529 assert!(serde_json::from_value::<TextDocumentSyncKind>(json!("_future")).is_err());
3530 }
3531
3532 #[test]
3533 fn test_document_event_capabilities_drop_unknown_did_change_sync_kind() {
3534 let caps: NesDocumentEventCapabilities = serde_json::from_value(json!({
3535 "didChange": {
3536 "syncKind": "_future"
3537 }
3538 }))
3539 .unwrap();
3540
3541 assert_eq!(caps.did_change, None);
3542 }
3543
3544 #[test]
3545 fn test_document_did_change_capabilities_requires_sync_kind() {
3546 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
3547 }
3548
3549 #[test]
3550 fn test_nes_suggest_response_serialization() {
3551 let response = SuggestNesResponse::new(vec![
3552 NesSuggestion::Edit(NesEditSuggestion::new(
3553 "sugg_001",
3554 "file:///path/to/file.rs",
3555 vec![NesTextEdit::new(
3556 Range::new(Position::new(5, 0), Position::new(5, 10)),
3557 "let result = helper();",
3558 )],
3559 )),
3560 NesSuggestion::Jump(NesJumpSuggestion::new(
3561 "sugg_002",
3562 "file:///path/to/other.rs",
3563 Position::new(10, 0),
3564 )),
3565 ]);
3566
3567 let json = serde_json::to_value(&response).unwrap();
3568 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3569 assert_eq!(json["suggestions"][0]["kind"], "edit");
3570 assert_eq!(json["suggestions"][1]["kind"], "jump");
3571 }
3572}