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
1394#[serde_as]
1398#[skip_serializing_none]
1399#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1400#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1401#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME)))]
1402#[serde(rename_all = "camelCase")]
1403#[non_exhaustive]
1404pub struct StartNesRequest {
1405 #[serde_as(deserialize_as = "DefaultOnError")]
1407 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1408 #[cfg_attr(feature = "schemars", schemars(url))]
1409 #[serde(default)]
1410 pub workspace_uri: Option<String>,
1411 #[serde(default)]
1413 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1414 #[serde_as(deserialize_as = "DefaultOnError")]
1416 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1417 #[serde(default)]
1418 pub repository: Option<NesRepository>,
1419 #[serde_as(deserialize_as = "DefaultOnError")]
1425 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1426 #[serde(default)]
1427 #[serde(rename = "_meta")]
1428 pub meta: Option<Meta>,
1429}
1430
1431impl StartNesRequest {
1432 #[must_use]
1434 pub fn new() -> Self {
1435 Self {
1436 workspace_uri: None,
1437 workspace_folders: None,
1438 repository: None,
1439 meta: None,
1440 }
1441 }
1442
1443 #[must_use]
1445 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1446 self.workspace_uri = workspace_uri.into_option();
1447 self
1448 }
1449
1450 #[must_use]
1452 pub fn workspace_folders(
1453 mut self,
1454 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1455 ) -> Self {
1456 self.workspace_folders = workspace_folders.into_option();
1457 self
1458 }
1459
1460 #[must_use]
1462 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1463 self.repository = repository.into_option();
1464 self
1465 }
1466
1467 #[must_use]
1473 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1474 self.meta = meta.into_option();
1475 self
1476 }
1477}
1478
1479impl Default for StartNesRequest {
1480 fn default() -> Self {
1481 Self::new()
1482 }
1483}
1484
1485#[serde_as]
1487#[skip_serializing_none]
1488#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1489#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1490#[serde(rename_all = "camelCase")]
1491#[non_exhaustive]
1492pub struct WorkspaceFolder {
1493 #[cfg_attr(feature = "schemars", schemars(url))]
1495 pub uri: String,
1496 pub name: String,
1498 #[serde_as(deserialize_as = "DefaultOnError")]
1504 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1505 #[serde(default)]
1506 #[serde(rename = "_meta")]
1507 pub meta: Option<Meta>,
1508}
1509
1510impl WorkspaceFolder {
1511 #[must_use]
1513 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1514 Self {
1515 uri: uri.into(),
1516 name: name.into(),
1517 meta: None,
1518 }
1519 }
1520
1521 #[must_use]
1527 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1528 self.meta = meta.into_option();
1529 self
1530 }
1531}
1532
1533#[serde_as]
1535#[skip_serializing_none]
1536#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1537#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1538#[serde(rename_all = "camelCase")]
1539#[non_exhaustive]
1540pub struct NesRepository {
1541 pub name: String,
1543 pub owner: String,
1545 pub remote_url: String,
1547 #[serde_as(deserialize_as = "DefaultOnError")]
1553 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1554 #[serde(default)]
1555 #[serde(rename = "_meta")]
1556 pub meta: Option<Meta>,
1557}
1558
1559impl NesRepository {
1560 #[must_use]
1562 pub fn new(
1563 name: impl Into<String>,
1564 owner: impl Into<String>,
1565 remote_url: impl Into<String>,
1566 ) -> Self {
1567 Self {
1568 name: name.into(),
1569 owner: owner.into(),
1570 remote_url: remote_url.into(),
1571 meta: None,
1572 }
1573 }
1574
1575 #[must_use]
1581 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1582 self.meta = meta.into_option();
1583 self
1584 }
1585}
1586
1587#[serde_as]
1589#[skip_serializing_none]
1590#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1591#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1592#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME)))]
1593#[serde(rename_all = "camelCase")]
1594#[non_exhaustive]
1595pub struct StartNesResponse {
1596 pub session_id: SessionId,
1598 #[serde_as(deserialize_as = "DefaultOnError")]
1604 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1605 #[serde(default)]
1606 #[serde(rename = "_meta")]
1607 pub meta: Option<Meta>,
1608}
1609
1610impl StartNesResponse {
1611 #[must_use]
1613 pub fn new(session_id: impl Into<SessionId>) -> Self {
1614 Self {
1615 session_id: session_id.into(),
1616 meta: None,
1617 }
1618 }
1619
1620 #[must_use]
1626 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1627 self.meta = meta.into_option();
1628 self
1629 }
1630}
1631
1632#[serde_as]
1639#[skip_serializing_none]
1640#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1641#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1642#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME)))]
1643#[serde(rename_all = "camelCase")]
1644#[non_exhaustive]
1645pub struct CloseNesRequest {
1646 pub session_id: SessionId,
1648 #[serde_as(deserialize_as = "DefaultOnError")]
1654 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1655 #[serde(default)]
1656 #[serde(rename = "_meta")]
1657 pub meta: Option<Meta>,
1658}
1659
1660impl CloseNesRequest {
1661 #[must_use]
1663 pub fn new(session_id: impl Into<SessionId>) -> Self {
1664 Self {
1665 session_id: session_id.into(),
1666 meta: None,
1667 }
1668 }
1669
1670 #[must_use]
1676 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1677 self.meta = meta.into_option();
1678 self
1679 }
1680}
1681
1682#[serde_as]
1684#[skip_serializing_none]
1685#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1686#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1687#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME)))]
1688#[serde(rename_all = "camelCase")]
1689#[non_exhaustive]
1690pub struct CloseNesResponse {
1691 #[serde_as(deserialize_as = "DefaultOnError")]
1697 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1698 #[serde(default)]
1699 #[serde(rename = "_meta")]
1700 pub meta: Option<Meta>,
1701}
1702
1703impl CloseNesResponse {
1704 #[must_use]
1706 pub fn new() -> Self {
1707 Self::default()
1708 }
1709
1710 #[must_use]
1716 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1717 self.meta = meta.into_option();
1718 self
1719 }
1720}
1721
1722#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1726#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1727#[non_exhaustive]
1728pub enum NesTriggerKind {
1729 #[serde(rename = "automatic")]
1731 Automatic,
1732 #[serde(rename = "diagnostic")]
1734 Diagnostic,
1735 #[serde(rename = "manual")]
1737 Manual,
1738 #[serde(untagged)]
1744 Other(String),
1745}
1746
1747#[serde_as]
1749#[skip_serializing_none]
1750#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1751#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1752#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME)))]
1753#[serde(rename_all = "camelCase")]
1754#[non_exhaustive]
1755pub struct SuggestNesRequest {
1756 pub session_id: SessionId,
1758 #[cfg_attr(feature = "schemars", schemars(url))]
1760 pub uri: String,
1761 pub version: i64,
1763 pub position: Position,
1765 #[serde(default)]
1767 pub selection: Option<Range>,
1768 pub trigger_kind: NesTriggerKind,
1770 #[serde(default)]
1772 pub context: Option<NesSuggestContext>,
1773 #[serde_as(deserialize_as = "DefaultOnError")]
1779 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1780 #[serde(default)]
1781 #[serde(rename = "_meta")]
1782 pub meta: Option<Meta>,
1783}
1784
1785impl SuggestNesRequest {
1786 #[must_use]
1788 pub fn new(
1789 session_id: impl Into<SessionId>,
1790 uri: impl Into<String>,
1791 version: i64,
1792 position: Position,
1793 trigger_kind: NesTriggerKind,
1794 ) -> Self {
1795 Self {
1796 session_id: session_id.into(),
1797 uri: uri.into(),
1798 version,
1799 position,
1800 selection: None,
1801 trigger_kind,
1802 context: None,
1803 meta: None,
1804 }
1805 }
1806
1807 #[must_use]
1809 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1810 self.selection = selection.into_option();
1811 self
1812 }
1813
1814 #[must_use]
1816 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1817 self.context = context.into_option();
1818 self
1819 }
1820
1821 #[must_use]
1827 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1828 self.meta = meta.into_option();
1829 self
1830 }
1831}
1832
1833#[serde_as]
1835#[skip_serializing_none]
1836#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1837#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1838#[serde(rename_all = "camelCase")]
1839#[non_exhaustive]
1840pub struct NesSuggestContext {
1841 #[serde(default)]
1843 pub recent_files: Option<Vec<NesRecentFile>>,
1844 #[serde(default)]
1846 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1847 #[serde(default)]
1849 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1850 #[serde(default)]
1852 pub user_actions: Option<Vec<NesUserAction>>,
1853 #[serde(default)]
1855 pub open_files: Option<Vec<NesOpenFile>>,
1856 #[serde(default)]
1858 pub diagnostics: Option<Vec<NesDiagnostic>>,
1859 #[serde_as(deserialize_as = "DefaultOnError")]
1865 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1866 #[serde(default)]
1867 #[serde(rename = "_meta")]
1868 pub meta: Option<Meta>,
1869}
1870
1871impl NesSuggestContext {
1872 #[must_use]
1874 pub fn new() -> Self {
1875 Self::default()
1876 }
1877
1878 #[must_use]
1880 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1881 self.recent_files = recent_files.into_option();
1882 self
1883 }
1884
1885 #[must_use]
1887 pub fn related_snippets(
1888 mut self,
1889 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1890 ) -> Self {
1891 self.related_snippets = related_snippets.into_option();
1892 self
1893 }
1894
1895 #[must_use]
1897 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1898 self.edit_history = edit_history.into_option();
1899 self
1900 }
1901
1902 #[must_use]
1904 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1905 self.user_actions = user_actions.into_option();
1906 self
1907 }
1908
1909 #[must_use]
1911 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1912 self.open_files = open_files.into_option();
1913 self
1914 }
1915
1916 #[must_use]
1918 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1919 self.diagnostics = diagnostics.into_option();
1920 self
1921 }
1922
1923 #[must_use]
1929 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1930 self.meta = meta.into_option();
1931 self
1932 }
1933}
1934
1935#[serde_as]
1937#[skip_serializing_none]
1938#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1939#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1940#[serde(rename_all = "camelCase")]
1941#[non_exhaustive]
1942pub struct NesRecentFile {
1943 #[cfg_attr(feature = "schemars", schemars(url))]
1945 pub uri: String,
1946 pub language_id: String,
1948 pub text: String,
1950 #[serde_as(deserialize_as = "DefaultOnError")]
1956 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
1957 #[serde(default)]
1958 #[serde(rename = "_meta")]
1959 pub meta: Option<Meta>,
1960}
1961
1962impl NesRecentFile {
1963 #[must_use]
1965 pub fn new(
1966 uri: impl Into<String>,
1967 language_id: impl Into<String>,
1968 text: impl Into<String>,
1969 ) -> Self {
1970 Self {
1971 uri: uri.into(),
1972 language_id: language_id.into(),
1973 text: text.into(),
1974 meta: None,
1975 }
1976 }
1977
1978 #[must_use]
1984 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1985 self.meta = meta.into_option();
1986 self
1987 }
1988}
1989
1990#[serde_as]
1992#[skip_serializing_none]
1993#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1994#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1995#[serde(rename_all = "camelCase")]
1996#[non_exhaustive]
1997pub struct NesRelatedSnippet {
1998 #[cfg_attr(feature = "schemars", schemars(url))]
2000 pub uri: String,
2001 pub excerpts: Vec<NesExcerpt>,
2003 #[serde_as(deserialize_as = "DefaultOnError")]
2009 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2010 #[serde(default)]
2011 #[serde(rename = "_meta")]
2012 pub meta: Option<Meta>,
2013}
2014
2015impl NesRelatedSnippet {
2016 #[must_use]
2018 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
2019 Self {
2020 uri: uri.into(),
2021 excerpts,
2022 meta: None,
2023 }
2024 }
2025
2026 #[must_use]
2032 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2033 self.meta = meta.into_option();
2034 self
2035 }
2036}
2037
2038#[serde_as]
2040#[skip_serializing_none]
2041#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2042#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2043#[serde(rename_all = "camelCase")]
2044#[non_exhaustive]
2045pub struct NesExcerpt {
2046 pub start_line: u32,
2048 pub end_line: u32,
2050 pub text: String,
2052 #[serde_as(deserialize_as = "DefaultOnError")]
2058 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2059 #[serde(default)]
2060 #[serde(rename = "_meta")]
2061 pub meta: Option<Meta>,
2062}
2063
2064impl NesExcerpt {
2065 #[must_use]
2067 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
2068 Self {
2069 start_line,
2070 end_line,
2071 text: text.into(),
2072 meta: None,
2073 }
2074 }
2075
2076 #[must_use]
2082 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2083 self.meta = meta.into_option();
2084 self
2085 }
2086}
2087
2088#[serde_as]
2090#[skip_serializing_none]
2091#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2092#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2093#[serde(rename_all = "camelCase")]
2094#[non_exhaustive]
2095pub struct NesEditHistoryEntry {
2096 #[cfg_attr(feature = "schemars", schemars(url))]
2098 pub uri: String,
2099 pub diff: String,
2101 #[serde_as(deserialize_as = "DefaultOnError")]
2107 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2108 #[serde(default)]
2109 #[serde(rename = "_meta")]
2110 pub meta: Option<Meta>,
2111}
2112
2113impl NesEditHistoryEntry {
2114 #[must_use]
2116 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
2117 Self {
2118 uri: uri.into(),
2119 diff: diff.into(),
2120 meta: None,
2121 }
2122 }
2123
2124 #[must_use]
2130 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2131 self.meta = meta.into_option();
2132 self
2133 }
2134}
2135
2136#[serde_as]
2138#[skip_serializing_none]
2139#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2140#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2141#[serde(rename_all = "camelCase")]
2142#[non_exhaustive]
2143pub struct NesUserAction {
2144 pub action: String,
2146 #[cfg_attr(feature = "schemars", schemars(url))]
2148 pub uri: String,
2149 pub position: Position,
2151 pub timestamp_ms: u64,
2153 #[serde_as(deserialize_as = "DefaultOnError")]
2159 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2160 #[serde(default)]
2161 #[serde(rename = "_meta")]
2162 pub meta: Option<Meta>,
2163}
2164
2165impl NesUserAction {
2166 #[must_use]
2168 pub fn new(
2169 action: impl Into<String>,
2170 uri: impl Into<String>,
2171 position: Position,
2172 timestamp_ms: u64,
2173 ) -> Self {
2174 Self {
2175 action: action.into(),
2176 uri: uri.into(),
2177 position,
2178 timestamp_ms,
2179 meta: None,
2180 }
2181 }
2182
2183 #[must_use]
2189 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2190 self.meta = meta.into_option();
2191 self
2192 }
2193}
2194
2195#[serde_as]
2197#[skip_serializing_none]
2198#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2199#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2200#[serde(rename_all = "camelCase")]
2201#[non_exhaustive]
2202pub struct NesOpenFile {
2203 #[cfg_attr(feature = "schemars", schemars(url))]
2205 pub uri: String,
2206 pub language_id: String,
2208 #[serde_as(deserialize_as = "DefaultOnError")]
2210 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2211 #[serde(default)]
2212 pub visible_range: Option<Range>,
2213 #[serde_as(deserialize_as = "DefaultOnError")]
2215 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2216 #[serde(default)]
2217 pub last_focused_ms: Option<u64>,
2218 #[serde_as(deserialize_as = "DefaultOnError")]
2224 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2225 #[serde(default)]
2226 #[serde(rename = "_meta")]
2227 pub meta: Option<Meta>,
2228}
2229
2230impl NesOpenFile {
2231 #[must_use]
2233 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
2234 Self {
2235 uri: uri.into(),
2236 language_id: language_id.into(),
2237 visible_range: None,
2238 last_focused_ms: None,
2239 meta: None,
2240 }
2241 }
2242
2243 #[must_use]
2245 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
2246 self.visible_range = visible_range.into_option();
2247 self
2248 }
2249
2250 #[must_use]
2252 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
2253 self.last_focused_ms = last_focused_ms.into_option();
2254 self
2255 }
2256
2257 #[must_use]
2263 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2264 self.meta = meta.into_option();
2265 self
2266 }
2267}
2268
2269#[serde_as]
2271#[skip_serializing_none]
2272#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2273#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2274#[serde(rename_all = "camelCase")]
2275#[non_exhaustive]
2276pub struct NesDiagnostic {
2277 #[cfg_attr(feature = "schemars", schemars(url))]
2279 pub uri: String,
2280 pub range: Range,
2282 pub severity: NesDiagnosticSeverity,
2284 pub message: String,
2286 #[serde_as(deserialize_as = "DefaultOnError")]
2292 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2293 #[serde(default)]
2294 #[serde(rename = "_meta")]
2295 pub meta: Option<Meta>,
2296}
2297
2298impl NesDiagnostic {
2299 #[must_use]
2301 pub fn new(
2302 uri: impl Into<String>,
2303 range: Range,
2304 severity: NesDiagnosticSeverity,
2305 message: impl Into<String>,
2306 ) -> Self {
2307 Self {
2308 uri: uri.into(),
2309 range,
2310 severity,
2311 message: message.into(),
2312 meta: None,
2313 }
2314 }
2315
2316 #[must_use]
2322 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2323 self.meta = meta.into_option();
2324 self
2325 }
2326}
2327
2328#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2330#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2331#[non_exhaustive]
2332pub enum NesDiagnosticSeverity {
2333 #[serde(rename = "error")]
2335 Error,
2336 #[serde(rename = "warning")]
2338 Warning,
2339 #[serde(rename = "information")]
2341 Information,
2342 #[serde(rename = "hint")]
2344 Hint,
2345 #[serde(untagged)]
2351 Other(String),
2352}
2353
2354#[serde_as]
2358#[skip_serializing_none]
2359#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2360#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2361#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME)))]
2362#[serde(rename_all = "camelCase")]
2363#[non_exhaustive]
2364pub struct SuggestNesResponse {
2365 pub suggestions: Vec<NesSuggestion>,
2367 #[serde_as(deserialize_as = "DefaultOnError")]
2373 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2374 #[serde(default)]
2375 #[serde(rename = "_meta")]
2376 pub meta: Option<Meta>,
2377}
2378
2379impl SuggestNesResponse {
2380 #[must_use]
2382 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2383 Self {
2384 suggestions,
2385 meta: None,
2386 }
2387 }
2388
2389 #[must_use]
2395 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2396 self.meta = meta.into_option();
2397 self
2398 }
2399}
2400
2401#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2403#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2404#[serde(tag = "kind", rename_all = "camelCase")]
2405#[non_exhaustive]
2406pub enum NesSuggestion {
2407 Edit(NesEditSuggestion),
2409 Jump(NesJumpSuggestion),
2411 Rename(NesRenameSuggestion),
2413 SearchAndReplace(NesSearchAndReplaceSuggestion),
2415 #[serde(untagged)]
2425 Other(OtherNesSuggestion),
2426}
2427
2428#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2430#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
2431#[cfg_attr(feature = "schemars", schemars(inline))]
2432#[cfg_attr(feature = "schemars", schemars(transform = other_nes_suggestion_schema))]
2433#[serde(rename_all = "camelCase")]
2434#[non_exhaustive]
2435pub struct OtherNesSuggestion {
2436 pub kind: String,
2442 pub suggestion_id: NesSuggestionId,
2444 #[serde(flatten)]
2446 pub fields: BTreeMap<String, serde_json::Value>,
2447}
2448
2449impl OtherNesSuggestion {
2450 #[must_use]
2452 pub fn new(
2453 kind: impl Into<String>,
2454 suggestion_id: impl Into<NesSuggestionId>,
2455 mut fields: BTreeMap<String, serde_json::Value>,
2456 ) -> Self {
2457 fields.remove("kind");
2458 fields.remove("suggestionId");
2459 Self {
2460 kind: kind.into(),
2461 suggestion_id: suggestion_id.into(),
2462 fields,
2463 }
2464 }
2465}
2466
2467impl<'de> Deserialize<'de> for OtherNesSuggestion {
2468 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2469 where
2470 D: serde::Deserializer<'de>,
2471 {
2472 let mut fields = BTreeMap::<String, serde_json::Value>::deserialize(deserializer)?;
2473 let kind = fields
2474 .remove("kind")
2475 .ok_or_else(|| serde::de::Error::missing_field("kind"))?;
2476 let serde_json::Value::String(kind) = kind else {
2477 return Err(serde::de::Error::custom("`kind` must be a string"));
2478 };
2479 let suggestion_id = fields
2480 .remove("suggestionId")
2481 .ok_or_else(|| serde::de::Error::missing_field("suggestionId"))?;
2482 let serde_json::Value::String(suggestion_id) = suggestion_id else {
2483 return Err(serde::de::Error::custom("`suggestionId` must be a string"));
2484 };
2485
2486 if is_known_nes_suggestion_kind(&kind) {
2487 return Err(serde::de::Error::custom(format!(
2488 "known NES suggestion `{kind}` did not match its schema"
2489 )));
2490 }
2491
2492 Ok(Self {
2493 kind,
2494 suggestion_id: NesSuggestionId::new(suggestion_id),
2495 fields,
2496 })
2497 }
2498}
2499
2500fn is_known_nes_suggestion_kind(kind: &str) -> bool {
2501 matches!(kind, "edit" | "jump" | "rename" | "searchAndReplace")
2502}
2503
2504#[cfg(feature = "schemars")]
2505fn other_nes_suggestion_schema(schema: &mut Schema) {
2506 super::schema_util::reject_known_string_discriminators(
2507 schema,
2508 "kind",
2509 &["edit", "jump", "rename", "searchAndReplace"],
2510 );
2511}
2512
2513#[serde_as]
2515#[skip_serializing_none]
2516#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2517#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2518#[serde(rename_all = "camelCase")]
2519#[non_exhaustive]
2520pub struct NesEditSuggestion {
2521 pub suggestion_id: NesSuggestionId,
2523 #[cfg_attr(feature = "schemars", schemars(url))]
2525 pub uri: String,
2526 #[cfg_attr(feature = "schemars", schemars(length(min = 1)))]
2528 pub edits: Vec<NesTextEdit>,
2529 #[serde_as(deserialize_as = "DefaultOnError")]
2531 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2532 #[serde(default)]
2533 pub cursor_position: Option<Position>,
2534 #[serde_as(deserialize_as = "DefaultOnError")]
2540 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2541 #[serde(default)]
2542 #[serde(rename = "_meta")]
2543 pub meta: Option<Meta>,
2544}
2545
2546impl NesEditSuggestion {
2547 #[must_use]
2549 pub fn new(
2550 suggestion_id: impl Into<NesSuggestionId>,
2551 uri: impl Into<String>,
2552 edits: Vec<NesTextEdit>,
2553 ) -> Self {
2554 Self {
2555 suggestion_id: suggestion_id.into(),
2556 uri: uri.into(),
2557 edits,
2558 cursor_position: None,
2559 meta: None,
2560 }
2561 }
2562
2563 #[must_use]
2565 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2566 self.cursor_position = cursor_position.into_option();
2567 self
2568 }
2569
2570 #[must_use]
2576 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2577 self.meta = meta.into_option();
2578 self
2579 }
2580}
2581
2582#[serde_as]
2584#[skip_serializing_none]
2585#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2586#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2587#[serde(rename_all = "camelCase")]
2588#[non_exhaustive]
2589pub struct NesTextEdit {
2590 pub range: Range,
2592 pub new_text: String,
2594 #[serde_as(deserialize_as = "DefaultOnError")]
2600 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2601 #[serde(default)]
2602 #[serde(rename = "_meta")]
2603 pub meta: Option<Meta>,
2604}
2605
2606impl NesTextEdit {
2607 #[must_use]
2609 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2610 Self {
2611 range,
2612 new_text: new_text.into(),
2613 meta: None,
2614 }
2615 }
2616
2617 #[must_use]
2623 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2624 self.meta = meta.into_option();
2625 self
2626 }
2627}
2628
2629#[serde_as]
2631#[skip_serializing_none]
2632#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2633#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2634#[serde(rename_all = "camelCase")]
2635#[non_exhaustive]
2636pub struct NesJumpSuggestion {
2637 pub suggestion_id: NesSuggestionId,
2639 #[cfg_attr(feature = "schemars", schemars(url))]
2641 pub uri: String,
2642 pub position: Position,
2644 #[serde_as(deserialize_as = "DefaultOnError")]
2650 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2651 #[serde(default)]
2652 #[serde(rename = "_meta")]
2653 pub meta: Option<Meta>,
2654}
2655
2656impl NesJumpSuggestion {
2657 #[must_use]
2659 pub fn new(
2660 suggestion_id: impl Into<NesSuggestionId>,
2661 uri: impl Into<String>,
2662 position: Position,
2663 ) -> Self {
2664 Self {
2665 suggestion_id: suggestion_id.into(),
2666 uri: uri.into(),
2667 position,
2668 meta: None,
2669 }
2670 }
2671
2672 #[must_use]
2678 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2679 self.meta = meta.into_option();
2680 self
2681 }
2682}
2683
2684#[serde_as]
2686#[skip_serializing_none]
2687#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2688#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2689#[serde(rename_all = "camelCase")]
2690#[non_exhaustive]
2691pub struct NesRenameSuggestion {
2692 pub suggestion_id: NesSuggestionId,
2694 #[cfg_attr(feature = "schemars", schemars(url))]
2696 pub uri: String,
2697 pub position: Position,
2699 pub new_name: String,
2701 #[serde_as(deserialize_as = "DefaultOnError")]
2707 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2708 #[serde(default)]
2709 #[serde(rename = "_meta")]
2710 pub meta: Option<Meta>,
2711}
2712
2713impl NesRenameSuggestion {
2714 #[must_use]
2716 pub fn new(
2717 suggestion_id: impl Into<NesSuggestionId>,
2718 uri: impl Into<String>,
2719 position: Position,
2720 new_name: impl Into<String>,
2721 ) -> Self {
2722 Self {
2723 suggestion_id: suggestion_id.into(),
2724 uri: uri.into(),
2725 position,
2726 new_name: new_name.into(),
2727 meta: None,
2728 }
2729 }
2730
2731 #[must_use]
2737 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2738 self.meta = meta.into_option();
2739 self
2740 }
2741}
2742
2743#[serde_as]
2745#[skip_serializing_none]
2746#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2747#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2748#[serde(rename_all = "camelCase")]
2749#[non_exhaustive]
2750pub struct NesSearchAndReplaceSuggestion {
2751 pub suggestion_id: NesSuggestionId,
2753 #[cfg_attr(feature = "schemars", schemars(url))]
2755 pub uri: String,
2756 pub search: String,
2758 pub replace: String,
2760 #[serde(default)]
2762 pub is_regex: Option<bool>,
2763 #[serde_as(deserialize_as = "DefaultOnError")]
2769 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2770 #[serde(default)]
2771 #[serde(rename = "_meta")]
2772 pub meta: Option<Meta>,
2773}
2774
2775impl NesSearchAndReplaceSuggestion {
2776 #[must_use]
2778 pub fn new(
2779 suggestion_id: impl Into<NesSuggestionId>,
2780 uri: impl Into<String>,
2781 search: impl Into<String>,
2782 replace: impl Into<String>,
2783 ) -> Self {
2784 Self {
2785 suggestion_id: suggestion_id.into(),
2786 uri: uri.into(),
2787 search: search.into(),
2788 replace: replace.into(),
2789 is_regex: None,
2790 meta: None,
2791 }
2792 }
2793
2794 #[must_use]
2796 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2797 self.is_regex = is_regex.into_option();
2798 self
2799 }
2800
2801 #[must_use]
2807 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2808 self.meta = meta.into_option();
2809 self
2810 }
2811}
2812
2813#[serde_as]
2817#[skip_serializing_none]
2818#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2819#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2820#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME)))]
2821#[serde(rename_all = "camelCase")]
2822#[non_exhaustive]
2823pub struct AcceptNesNotification {
2824 pub session_id: SessionId,
2826 pub suggestion_id: NesSuggestionId,
2828 #[serde_as(deserialize_as = "DefaultOnError")]
2834 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2835 #[serde(default)]
2836 #[serde(rename = "_meta")]
2837 pub meta: Option<Meta>,
2838}
2839
2840impl AcceptNesNotification {
2841 #[must_use]
2843 pub fn new(
2844 session_id: impl Into<SessionId>,
2845 suggestion_id: impl Into<NesSuggestionId>,
2846 ) -> Self {
2847 Self {
2848 session_id: session_id.into(),
2849 suggestion_id: suggestion_id.into(),
2850 meta: None,
2851 }
2852 }
2853
2854 #[must_use]
2860 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2861 self.meta = meta.into_option();
2862 self
2863 }
2864}
2865
2866#[serde_as]
2868#[skip_serializing_none]
2869#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2870#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2871#[cfg_attr(feature = "schemars", schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME)))]
2872#[serde(rename_all = "camelCase")]
2873#[non_exhaustive]
2874pub struct RejectNesNotification {
2875 pub session_id: SessionId,
2877 pub suggestion_id: NesSuggestionId,
2879 #[serde_as(deserialize_as = "DefaultOnError")]
2881 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2882 #[serde(default)]
2883 pub reason: Option<NesRejectReason>,
2884 #[serde_as(deserialize_as = "DefaultOnError")]
2890 #[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
2891 #[serde(default)]
2892 #[serde(rename = "_meta")]
2893 pub meta: Option<Meta>,
2894}
2895
2896impl RejectNesNotification {
2897 #[must_use]
2899 pub fn new(
2900 session_id: impl Into<SessionId>,
2901 suggestion_id: impl Into<NesSuggestionId>,
2902 ) -> Self {
2903 Self {
2904 session_id: session_id.into(),
2905 suggestion_id: suggestion_id.into(),
2906 reason: None,
2907 meta: None,
2908 }
2909 }
2910
2911 #[must_use]
2913 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2914 self.reason = reason.into_option();
2915 self
2916 }
2917
2918 #[must_use]
2924 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2925 self.meta = meta.into_option();
2926 self
2927 }
2928}
2929
2930#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2932#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2933#[non_exhaustive]
2934pub enum NesRejectReason {
2935 #[serde(rename = "rejected")]
2937 Rejected,
2938 #[serde(rename = "ignored")]
2940 Ignored,
2941 #[serde(rename = "replaced")]
2943 Replaced,
2944 #[serde(rename = "cancelled")]
2946 Cancelled,
2947 #[serde(untagged)]
2953 Other(String),
2954}
2955
2956#[cfg(test)]
2957mod tests {
2958 use super::*;
2959 use serde_json::json;
2960
2961 #[test]
2962 fn test_position_encoding_kind_serialization() {
2963 assert_eq!(
2964 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2965 json!("utf-16")
2966 );
2967 assert_eq!(
2968 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2969 json!("utf-32")
2970 );
2971 assert_eq!(
2972 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2973 json!("utf-8")
2974 );
2975
2976 assert_eq!(
2977 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2978 PositionEncodingKind::Utf16
2979 );
2980 assert_eq!(
2981 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2982 PositionEncodingKind::Utf32
2983 );
2984 assert_eq!(
2985 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2986 PositionEncodingKind::Utf8
2987 );
2988 assert!(serde_json::from_value::<PositionEncodingKind>(json!("_future")).is_err());
2989 }
2990
2991 #[test]
2992 fn test_client_capabilities_skip_unknown_position_encodings() {
2993 let caps: crate::v2::ClientCapabilities = serde_json::from_value(json!({
2994 "positionEncodings": ["_future", "utf-8", "utf-16"]
2995 }))
2996 .unwrap();
2997
2998 assert_eq!(
2999 caps.position_encodings,
3000 vec![PositionEncodingKind::Utf8, PositionEncodingKind::Utf16]
3001 );
3002 }
3003
3004 #[test]
3005 fn test_agent_nes_capabilities_serialization() {
3006 let caps = NesCapabilities::new()
3007 .events(
3008 NesEventCapabilities::new().document(
3009 NesDocumentEventCapabilities::new()
3010 .did_open(NesDocumentDidOpenCapabilities::default())
3011 .did_change(NesDocumentDidChangeCapabilities::new(
3012 TextDocumentSyncKind::Incremental,
3013 ))
3014 .did_close(NesDocumentDidCloseCapabilities::default())
3015 .did_save(NesDocumentDidSaveCapabilities::default())
3016 .did_focus(NesDocumentDidFocusCapabilities::default()),
3017 ),
3018 )
3019 .context(
3020 NesContextCapabilities::new()
3021 .recent_files(NesRecentFilesCapabilities {
3022 max_count: Some(10),
3023 meta: None,
3024 })
3025 .related_snippets(NesRelatedSnippetsCapabilities::default())
3026 .edit_history(NesEditHistoryCapabilities {
3027 max_count: Some(6),
3028 meta: None,
3029 })
3030 .user_actions(NesUserActionsCapabilities {
3031 max_count: Some(16),
3032 meta: None,
3033 })
3034 .open_files(NesOpenFilesCapabilities::default())
3035 .diagnostics(NesDiagnosticsCapabilities::default()),
3036 );
3037
3038 let json = serde_json::to_value(&caps).unwrap();
3039 assert_eq!(
3040 json,
3041 json!({
3042 "events": {
3043 "document": {
3044 "didOpen": {},
3045 "didChange": {
3046 "syncKind": "incremental"
3047 },
3048 "didClose": {},
3049 "didSave": {},
3050 "didFocus": {}
3051 }
3052 },
3053 "context": {
3054 "recentFiles": {
3055 "maxCount": 10
3056 },
3057 "relatedSnippets": {},
3058 "editHistory": {
3059 "maxCount": 6
3060 },
3061 "userActions": {
3062 "maxCount": 16
3063 },
3064 "openFiles": {},
3065 "diagnostics": {}
3066 }
3067 })
3068 );
3069
3070 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
3072 assert_eq!(deserialized, caps);
3073 }
3074
3075 #[test]
3076 fn test_client_nes_capabilities_serialization() {
3077 let caps = ClientNesCapabilities::new()
3078 .jump(NesJumpCapabilities::default())
3079 .rename(NesRenameCapabilities::default())
3080 .search_and_replace(NesSearchAndReplaceCapabilities::default());
3081
3082 let json = serde_json::to_value(&caps).unwrap();
3083 assert_eq!(
3084 json,
3085 json!({
3086 "jump": {},
3087 "rename": {},
3088 "searchAndReplace": {}
3089 })
3090 );
3091
3092 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
3093 assert_eq!(deserialized, caps);
3094 }
3095
3096 #[test]
3097 fn test_document_did_open_serialization() {
3098 let notification = DidOpenDocumentNotification::new(
3099 "session_123",
3100 "file:///path/to/file.rs",
3101 "rust",
3102 1,
3103 "fn main() {\n println!(\"hello\");\n}\n",
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 "languageId": "rust",
3113 "version": 1,
3114 "text": "fn main() {\n println!(\"hello\");\n}\n"
3115 })
3116 );
3117
3118 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
3119 assert_eq!(deserialized, notification);
3120 }
3121
3122 #[test]
3123 fn test_document_did_change_incremental_serialization() {
3124 let notification = DidChangeDocumentNotification::new(
3125 "session_123",
3126 "file:///path/to/file.rs",
3127 2,
3128 vec![TextDocumentContentChangeEvent::incremental(
3129 Range::new(Position::new(1, 4), Position::new(1, 4)),
3130 "let x = 42;\n ",
3131 )],
3132 );
3133
3134 let json = serde_json::to_value(¬ification).unwrap();
3135 assert_eq!(
3136 json,
3137 json!({
3138 "sessionId": "session_123",
3139 "uri": "file:///path/to/file.rs",
3140 "version": 2,
3141 "contentChanges": [
3142 {
3143 "range": {
3144 "start": { "line": 1, "character": 4 },
3145 "end": { "line": 1, "character": 4 }
3146 },
3147 "text": "let x = 42;\n "
3148 }
3149 ]
3150 })
3151 );
3152 }
3153
3154 #[test]
3155 fn test_document_did_change_full_serialization() {
3156 let notification = DidChangeDocumentNotification::new(
3157 "session_123",
3158 "file:///path/to/file.rs",
3159 2,
3160 vec![TextDocumentContentChangeEvent::full(
3161 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
3162 )],
3163 );
3164
3165 let json = serde_json::to_value(¬ification).unwrap();
3166 assert_eq!(
3167 json,
3168 json!({
3169 "sessionId": "session_123",
3170 "uri": "file:///path/to/file.rs",
3171 "version": 2,
3172 "contentChanges": [
3173 {
3174 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
3175 }
3176 ]
3177 })
3178 );
3179 }
3180
3181 #[test]
3182 fn test_document_did_close_serialization() {
3183 let notification =
3184 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
3185 let json = serde_json::to_value(¬ification).unwrap();
3186 assert_eq!(
3187 json,
3188 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3189 );
3190 }
3191
3192 #[test]
3193 fn test_document_did_save_serialization() {
3194 let notification =
3195 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
3196 let json = serde_json::to_value(¬ification).unwrap();
3197 assert_eq!(
3198 json,
3199 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3200 );
3201 }
3202
3203 #[test]
3204 fn test_document_did_focus_serialization() {
3205 let notification = DidFocusDocumentNotification::new(
3206 "session_123",
3207 "file:///path/to/file.rs",
3208 2,
3209 Position::new(5, 12),
3210 Range::new(Position::new(0, 0), Position::new(45, 0)),
3211 );
3212
3213 let json = serde_json::to_value(¬ification).unwrap();
3214 assert_eq!(
3215 json,
3216 json!({
3217 "sessionId": "session_123",
3218 "uri": "file:///path/to/file.rs",
3219 "version": 2,
3220 "position": { "line": 5, "character": 12 },
3221 "visibleRange": {
3222 "start": { "line": 0, "character": 0 },
3223 "end": { "line": 45, "character": 0 }
3224 }
3225 })
3226 );
3227 }
3228
3229 #[test]
3230 fn test_nes_suggestion_edit_serialization() {
3231 let suggestion = NesSuggestion::Edit(
3232 NesEditSuggestion::new(
3233 "sugg_001",
3234 "file:///path/to/other_file.rs",
3235 vec![NesTextEdit::new(
3236 Range::new(Position::new(5, 0), Position::new(5, 10)),
3237 "let result = helper();",
3238 )],
3239 )
3240 .cursor_position(Position::new(5, 22)),
3241 );
3242
3243 let json = serde_json::to_value(&suggestion).unwrap();
3244 assert_eq!(
3245 json,
3246 json!({
3247 "kind": "edit",
3248 "suggestionId": "sugg_001",
3249 "uri": "file:///path/to/other_file.rs",
3250 "edits": [
3251 {
3252 "range": {
3253 "start": { "line": 5, "character": 0 },
3254 "end": { "line": 5, "character": 10 }
3255 },
3256 "newText": "let result = helper();"
3257 }
3258 ],
3259 "cursorPosition": { "line": 5, "character": 22 }
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_unknown_variant() {
3269 let suggestion: NesSuggestion = serde_json::from_value(json!({
3270 "kind": "_preview",
3271 "suggestionId": "sugg_001",
3272 "label": "Preview generated file"
3273 }))
3274 .unwrap();
3275
3276 let NesSuggestion::Other(unknown) = suggestion else {
3277 panic!("expected unknown NES suggestion");
3278 };
3279
3280 assert_eq!(unknown.kind, "_preview");
3281 assert_eq!(unknown.suggestion_id.to_string(), "sugg_001");
3282 assert!(!unknown.fields.contains_key("suggestionId"));
3283 assert_eq!(
3284 serde_json::to_value(NesSuggestion::Other(unknown)).unwrap(),
3285 json!({
3286 "kind": "_preview",
3287 "suggestionId": "sugg_001",
3288 "label": "Preview generated file"
3289 })
3290 );
3291 }
3292
3293 #[test]
3294 fn test_nes_suggestion_unknown_does_not_hide_malformed_known_variant() {
3295 assert!(
3296 serde_json::from_value::<NesSuggestion>(json!({
3297 "kind": "edit"
3298 }))
3299 .is_err()
3300 );
3301 }
3302
3303 #[test]
3304 fn test_nes_suggestion_jump_serialization() {
3305 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
3306 "sugg_002",
3307 "file:///path/to/other_file.rs",
3308 Position::new(15, 4),
3309 ));
3310
3311 let json = serde_json::to_value(&suggestion).unwrap();
3312 assert_eq!(
3313 json,
3314 json!({
3315 "kind": "jump",
3316 "suggestionId": "sugg_002",
3317 "uri": "file:///path/to/other_file.rs",
3318 "position": { "line": 15, "character": 4 }
3319 })
3320 );
3321
3322 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3323 assert_eq!(deserialized, suggestion);
3324 }
3325
3326 #[test]
3327 fn test_nes_suggestion_rename_serialization() {
3328 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
3329 "sugg_003",
3330 "file:///path/to/file.rs",
3331 Position::new(5, 10),
3332 "calculateTotal",
3333 ));
3334
3335 let json = serde_json::to_value(&suggestion).unwrap();
3336 assert_eq!(
3337 json,
3338 json!({
3339 "kind": "rename",
3340 "suggestionId": "sugg_003",
3341 "uri": "file:///path/to/file.rs",
3342 "position": { "line": 5, "character": 10 },
3343 "newName": "calculateTotal"
3344 })
3345 );
3346
3347 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3348 assert_eq!(deserialized, suggestion);
3349 }
3350
3351 #[test]
3352 fn test_nes_suggestion_search_and_replace_serialization() {
3353 let suggestion = NesSuggestion::SearchAndReplace(
3354 NesSearchAndReplaceSuggestion::new(
3355 "sugg_004",
3356 "file:///path/to/file.rs",
3357 "oldFunction",
3358 "newFunction",
3359 )
3360 .is_regex(false),
3361 );
3362
3363 let json = serde_json::to_value(&suggestion).unwrap();
3364 assert_eq!(
3365 json,
3366 json!({
3367 "kind": "searchAndReplace",
3368 "suggestionId": "sugg_004",
3369 "uri": "file:///path/to/file.rs",
3370 "search": "oldFunction",
3371 "replace": "newFunction",
3372 "isRegex": false
3373 })
3374 );
3375
3376 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3377 assert_eq!(deserialized, suggestion);
3378 }
3379
3380 #[test]
3381 fn test_nes_start_request_serialization() {
3382 let request = StartNesRequest::new()
3383 .workspace_uri("file:///Users/alice/projects/my-app")
3384 .workspace_folders(vec![WorkspaceFolder::new(
3385 "file:///Users/alice/projects/my-app",
3386 "my-app",
3387 )])
3388 .repository(NesRepository::new(
3389 "my-app",
3390 "alice",
3391 "https://github.com/alice/my-app.git",
3392 ));
3393
3394 let json = serde_json::to_value(&request).unwrap();
3395 assert_eq!(
3396 json,
3397 json!({
3398 "workspaceUri": "file:///Users/alice/projects/my-app",
3399 "workspaceFolders": [
3400 {
3401 "uri": "file:///Users/alice/projects/my-app",
3402 "name": "my-app"
3403 }
3404 ],
3405 "repository": {
3406 "name": "my-app",
3407 "owner": "alice",
3408 "remoteUrl": "https://github.com/alice/my-app.git"
3409 }
3410 })
3411 );
3412 }
3413
3414 #[test]
3415 fn test_nes_start_response_serialization() {
3416 let response = StartNesResponse::new("session_abc123");
3417 let json = serde_json::to_value(&response).unwrap();
3418 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
3419 }
3420
3421 #[test]
3422 fn test_nes_trigger_kind_serialization() {
3423 assert_eq!(
3424 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
3425 json!("automatic")
3426 );
3427 assert_eq!(
3428 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
3429 json!("diagnostic")
3430 );
3431 assert_eq!(
3432 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
3433 json!("manual")
3434 );
3435 }
3436
3437 #[test]
3438 fn test_nes_reject_reason_serialization() {
3439 assert_eq!(
3440 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
3441 json!("rejected")
3442 );
3443 assert_eq!(
3444 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
3445 json!("ignored")
3446 );
3447 assert_eq!(
3448 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
3449 json!("replaced")
3450 );
3451 assert_eq!(
3452 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
3453 json!("cancelled")
3454 );
3455 }
3456
3457 #[test]
3458 fn test_nes_accept_notification_serialization() {
3459 let notification = AcceptNesNotification::new("session_123", "sugg_001");
3460 let json = serde_json::to_value(¬ification).unwrap();
3461 assert_eq!(
3462 json,
3463 json!({ "sessionId": "session_123", "suggestionId": "sugg_001" })
3464 );
3465 }
3466
3467 #[test]
3468 fn test_nes_reject_notification_serialization() {
3469 let notification =
3470 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
3471 let json = serde_json::to_value(¬ification).unwrap();
3472 assert_eq!(
3473 json,
3474 json!({ "sessionId": "session_123", "suggestionId": "sugg_001", "reason": "rejected" })
3475 );
3476 }
3477
3478 #[test]
3479 fn test_nes_suggest_request_with_context_serialization() {
3480 let request = SuggestNesRequest::new(
3481 "session_123",
3482 "file:///path/to/file.rs",
3483 2,
3484 Position::new(5, 12),
3485 NesTriggerKind::Automatic,
3486 )
3487 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
3488 .context(
3489 NesSuggestContext::new()
3490 .recent_files(vec![NesRecentFile::new(
3491 "file:///path/to/utils.rs",
3492 "rust",
3493 "pub fn helper() -> i32 { 42 }\n",
3494 )])
3495 .diagnostics(vec![NesDiagnostic::new(
3496 "file:///path/to/file.rs",
3497 Range::new(Position::new(5, 0), Position::new(5, 10)),
3498 NesDiagnosticSeverity::Error,
3499 "cannot find value `foo` in this scope",
3500 )]),
3501 );
3502
3503 let json = serde_json::to_value(&request).unwrap();
3504 assert_eq!(json["sessionId"], "session_123");
3505 assert_eq!(json["uri"], "file:///path/to/file.rs");
3506 assert_eq!(json["version"], 2);
3507 assert_eq!(json["triggerKind"], "automatic");
3508 assert_eq!(
3509 json["context"]["recentFiles"][0]["uri"],
3510 "file:///path/to/utils.rs"
3511 );
3512 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
3513 }
3514
3515 #[test]
3516 fn test_text_document_sync_kind_serialization() {
3517 assert_eq!(
3518 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
3519 json!("full")
3520 );
3521 assert_eq!(
3522 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
3523 json!("incremental")
3524 );
3525 assert!(serde_json::from_value::<TextDocumentSyncKind>(json!("_future")).is_err());
3526 }
3527
3528 #[test]
3529 fn test_document_event_capabilities_drop_unknown_did_change_sync_kind() {
3530 let caps: NesDocumentEventCapabilities = serde_json::from_value(json!({
3531 "didChange": {
3532 "syncKind": "_future"
3533 }
3534 }))
3535 .unwrap();
3536
3537 assert_eq!(caps.did_change, None);
3538 }
3539
3540 #[test]
3541 fn test_document_did_change_capabilities_requires_sync_kind() {
3542 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
3543 }
3544
3545 #[test]
3546 fn test_nes_suggest_response_serialization() {
3547 let response = SuggestNesResponse::new(vec![
3548 NesSuggestion::Edit(NesEditSuggestion::new(
3549 "sugg_001",
3550 "file:///path/to/file.rs",
3551 vec![NesTextEdit::new(
3552 Range::new(Position::new(5, 0), Position::new(5, 10)),
3553 "let result = helper();",
3554 )],
3555 )),
3556 NesSuggestion::Jump(NesJumpSuggestion::new(
3557 "sugg_002",
3558 "file:///path/to/other.rs",
3559 Position::new(10, 0),
3560 )),
3561 ]);
3562
3563 let json = serde_json::to_value(&response).unwrap();
3564 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3565 assert_eq!(json["suggestions"][0]["kind"], "edit");
3566 assert_eq!(json["suggestions"][1]["kind"], "jump");
3567 }
3568}