1use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use serde_with::{DefaultOnError, VecSkipError, serde_as, skip_serializing_none};
10
11use crate::{IntoOption, Meta, SessionId, SkipListener};
12
13pub(crate) const NES_START_METHOD_NAME: &str = "nes/start";
17pub(crate) const NES_SUGGEST_METHOD_NAME: &str = "nes/suggest";
19pub(crate) const NES_ACCEPT_METHOD_NAME: &str = "nes/accept";
21pub(crate) const NES_REJECT_METHOD_NAME: &str = "nes/reject";
23pub(crate) const NES_CLOSE_METHOD_NAME: &str = "nes/close";
25pub(crate) const DOCUMENT_DID_OPEN_METHOD_NAME: &str = "document/didOpen";
27pub(crate) const DOCUMENT_DID_CHANGE_METHOD_NAME: &str = "document/didChange";
29pub(crate) const DOCUMENT_DID_CLOSE_METHOD_NAME: &str = "document/didClose";
31pub(crate) const DOCUMENT_DID_SAVE_METHOD_NAME: &str = "document/didSave";
33pub(crate) const DOCUMENT_DID_FOCUS_METHOD_NAME: &str = "document/didFocus";
35
36#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
42#[non_exhaustive]
43pub enum PositionEncodingKind {
44 #[serde(rename = "utf-16")]
46 Utf16,
47 #[serde(rename = "utf-32")]
49 Utf32,
50 #[serde(rename = "utf-8")]
52 Utf8,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
59#[serde(rename_all = "camelCase")]
60#[non_exhaustive]
61pub struct Position {
62 pub line: u32,
64 pub character: u32,
66}
67
68impl Position {
69 #[must_use]
70 pub fn new(line: u32, character: u32) -> Self {
71 Self { line, character }
72 }
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
77#[serde(rename_all = "camelCase")]
78#[non_exhaustive]
79pub struct Range {
80 pub start: Position,
82 pub end: Position,
84}
85
86impl Range {
87 #[must_use]
88 pub fn new(start: Position, end: Position) -> Self {
89 Self { start, end }
90 }
91}
92
93#[serde_as]
97#[skip_serializing_none]
98#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
99#[serde(rename_all = "camelCase")]
100#[non_exhaustive]
101pub struct NesCapabilities {
102 #[serde_as(deserialize_as = "DefaultOnError")]
104 #[schemars(extend("x-deserialize-default-on-error" = true))]
105 #[serde(default)]
106 pub events: Option<NesEventCapabilities>,
107 #[serde_as(deserialize_as = "DefaultOnError")]
109 #[schemars(extend("x-deserialize-default-on-error" = true))]
110 #[serde(default)]
111 pub context: Option<NesContextCapabilities>,
112 #[serde(rename = "_meta")]
118 pub meta: Option<Meta>,
119}
120
121impl NesCapabilities {
122 #[must_use]
123 pub fn new() -> Self {
124 Self::default()
125 }
126
127 #[must_use]
128 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
129 self.events = events.into_option();
130 self
131 }
132
133 #[must_use]
134 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
135 self.context = context.into_option();
136 self
137 }
138
139 #[must_use]
145 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
146 self.meta = meta.into_option();
147 self
148 }
149}
150
151#[serde_as]
153#[skip_serializing_none]
154#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
155#[serde(rename_all = "camelCase")]
156#[non_exhaustive]
157pub struct NesEventCapabilities {
158 #[serde_as(deserialize_as = "DefaultOnError")]
160 #[schemars(extend("x-deserialize-default-on-error" = true))]
161 #[serde(default)]
162 pub document: Option<NesDocumentEventCapabilities>,
163 #[serde(rename = "_meta")]
169 pub meta: Option<Meta>,
170}
171
172impl NesEventCapabilities {
173 #[must_use]
174 pub fn new() -> Self {
175 Self::default()
176 }
177
178 #[must_use]
179 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
180 self.document = document.into_option();
181 self
182 }
183
184 #[must_use]
190 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
191 self.meta = meta.into_option();
192 self
193 }
194}
195
196#[serde_as]
198#[skip_serializing_none]
199#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
200#[serde(rename_all = "camelCase")]
201#[non_exhaustive]
202pub struct NesDocumentEventCapabilities {
203 #[serde_as(deserialize_as = "DefaultOnError")]
205 #[schemars(extend("x-deserialize-default-on-error" = true))]
206 #[serde(default)]
207 pub did_open: Option<NesDocumentDidOpenCapabilities>,
208 #[serde_as(deserialize_as = "DefaultOnError")]
210 #[schemars(extend("x-deserialize-default-on-error" = true))]
211 #[serde(default)]
212 pub did_change: Option<NesDocumentDidChangeCapabilities>,
213 #[serde_as(deserialize_as = "DefaultOnError")]
215 #[schemars(extend("x-deserialize-default-on-error" = true))]
216 #[serde(default)]
217 pub did_close: Option<NesDocumentDidCloseCapabilities>,
218 #[serde_as(deserialize_as = "DefaultOnError")]
220 #[schemars(extend("x-deserialize-default-on-error" = true))]
221 #[serde(default)]
222 pub did_save: Option<NesDocumentDidSaveCapabilities>,
223 #[serde_as(deserialize_as = "DefaultOnError")]
225 #[schemars(extend("x-deserialize-default-on-error" = true))]
226 #[serde(default)]
227 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
228 #[serde(rename = "_meta")]
234 pub meta: Option<Meta>,
235}
236
237impl NesDocumentEventCapabilities {
238 #[must_use]
239 pub fn new() -> Self {
240 Self::default()
241 }
242
243 #[must_use]
244 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
245 self.did_open = did_open.into_option();
246 self
247 }
248
249 #[must_use]
250 pub fn did_change(
251 mut self,
252 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
253 ) -> Self {
254 self.did_change = did_change.into_option();
255 self
256 }
257
258 #[must_use]
259 pub fn did_close(
260 mut self,
261 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
262 ) -> Self {
263 self.did_close = did_close.into_option();
264 self
265 }
266
267 #[must_use]
268 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
269 self.did_save = did_save.into_option();
270 self
271 }
272
273 #[must_use]
274 pub fn did_focus(
275 mut self,
276 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
277 ) -> Self {
278 self.did_focus = did_focus.into_option();
279 self
280 }
281
282 #[must_use]
288 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
289 self.meta = meta.into_option();
290 self
291 }
292}
293
294#[skip_serializing_none]
296#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
297#[serde(rename_all = "camelCase")]
298#[non_exhaustive]
299pub struct NesDocumentDidOpenCapabilities {
300 #[serde(rename = "_meta")]
306 pub meta: Option<Meta>,
307}
308
309impl NesDocumentDidOpenCapabilities {
310 #[must_use]
311 pub fn new() -> Self {
312 Self::default()
313 }
314}
315
316#[skip_serializing_none]
318#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
319#[serde(rename_all = "camelCase")]
320#[non_exhaustive]
321pub struct NesDocumentDidChangeCapabilities {
322 pub sync_kind: TextDocumentSyncKind,
324 #[serde(rename = "_meta")]
330 pub meta: Option<Meta>,
331}
332
333impl NesDocumentDidChangeCapabilities {
334 #[must_use]
335 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
336 Self {
337 sync_kind,
338 meta: None,
339 }
340 }
341
342 #[must_use]
348 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
349 self.meta = meta.into_option();
350 self
351 }
352}
353
354#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
356#[non_exhaustive]
357pub enum TextDocumentSyncKind {
358 #[serde(rename = "full")]
360 Full,
361 #[serde(rename = "incremental")]
363 Incremental,
364}
365
366#[skip_serializing_none]
368#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
369#[serde(rename_all = "camelCase")]
370#[non_exhaustive]
371pub struct NesDocumentDidCloseCapabilities {
372 #[serde(rename = "_meta")]
378 pub meta: Option<Meta>,
379}
380
381impl NesDocumentDidCloseCapabilities {
382 #[must_use]
383 pub fn new() -> Self {
384 Self::default()
385 }
386}
387
388#[skip_serializing_none]
390#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
391#[serde(rename_all = "camelCase")]
392#[non_exhaustive]
393pub struct NesDocumentDidSaveCapabilities {
394 #[serde(rename = "_meta")]
400 pub meta: Option<Meta>,
401}
402
403impl NesDocumentDidSaveCapabilities {
404 #[must_use]
405 pub fn new() -> Self {
406 Self::default()
407 }
408}
409
410#[skip_serializing_none]
412#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
413#[serde(rename_all = "camelCase")]
414#[non_exhaustive]
415pub struct NesDocumentDidFocusCapabilities {
416 #[serde(rename = "_meta")]
422 pub meta: Option<Meta>,
423}
424
425impl NesDocumentDidFocusCapabilities {
426 #[must_use]
427 pub fn new() -> Self {
428 Self::default()
429 }
430}
431
432#[serde_as]
434#[skip_serializing_none]
435#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
436#[serde(rename_all = "camelCase")]
437#[non_exhaustive]
438pub struct NesContextCapabilities {
439 #[serde_as(deserialize_as = "DefaultOnError")]
441 #[schemars(extend("x-deserialize-default-on-error" = true))]
442 #[serde(default)]
443 pub recent_files: Option<NesRecentFilesCapabilities>,
444 #[serde_as(deserialize_as = "DefaultOnError")]
446 #[schemars(extend("x-deserialize-default-on-error" = true))]
447 #[serde(default)]
448 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
449 #[serde_as(deserialize_as = "DefaultOnError")]
451 #[schemars(extend("x-deserialize-default-on-error" = true))]
452 #[serde(default)]
453 pub edit_history: Option<NesEditHistoryCapabilities>,
454 #[serde_as(deserialize_as = "DefaultOnError")]
456 #[schemars(extend("x-deserialize-default-on-error" = true))]
457 #[serde(default)]
458 pub user_actions: Option<NesUserActionsCapabilities>,
459 #[serde_as(deserialize_as = "DefaultOnError")]
461 #[schemars(extend("x-deserialize-default-on-error" = true))]
462 #[serde(default)]
463 pub open_files: Option<NesOpenFilesCapabilities>,
464 #[serde_as(deserialize_as = "DefaultOnError")]
466 #[schemars(extend("x-deserialize-default-on-error" = true))]
467 #[serde(default)]
468 pub diagnostics: Option<NesDiagnosticsCapabilities>,
469 #[serde(rename = "_meta")]
475 pub meta: Option<Meta>,
476}
477
478impl NesContextCapabilities {
479 #[must_use]
480 pub fn new() -> Self {
481 Self::default()
482 }
483
484 #[must_use]
485 pub fn recent_files(
486 mut self,
487 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
488 ) -> Self {
489 self.recent_files = recent_files.into_option();
490 self
491 }
492
493 #[must_use]
494 pub fn related_snippets(
495 mut self,
496 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
497 ) -> Self {
498 self.related_snippets = related_snippets.into_option();
499 self
500 }
501
502 #[must_use]
503 pub fn edit_history(
504 mut self,
505 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
506 ) -> Self {
507 self.edit_history = edit_history.into_option();
508 self
509 }
510
511 #[must_use]
512 pub fn user_actions(
513 mut self,
514 user_actions: impl IntoOption<NesUserActionsCapabilities>,
515 ) -> Self {
516 self.user_actions = user_actions.into_option();
517 self
518 }
519
520 #[must_use]
521 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
522 self.open_files = open_files.into_option();
523 self
524 }
525
526 #[must_use]
527 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
528 self.diagnostics = diagnostics.into_option();
529 self
530 }
531
532 #[must_use]
538 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
539 self.meta = meta.into_option();
540 self
541 }
542}
543
544#[skip_serializing_none]
546#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
547#[serde(rename_all = "camelCase")]
548#[non_exhaustive]
549pub struct NesRecentFilesCapabilities {
550 pub max_count: Option<u32>,
552 #[serde(rename = "_meta")]
558 pub meta: Option<Meta>,
559}
560
561impl NesRecentFilesCapabilities {
562 #[must_use]
563 pub fn new() -> Self {
564 Self::default()
565 }
566}
567
568#[skip_serializing_none]
570#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
571#[serde(rename_all = "camelCase")]
572#[non_exhaustive]
573pub struct NesRelatedSnippetsCapabilities {
574 #[serde(rename = "_meta")]
580 pub meta: Option<Meta>,
581}
582
583impl NesRelatedSnippetsCapabilities {
584 #[must_use]
585 pub fn new() -> Self {
586 Self::default()
587 }
588}
589
590#[skip_serializing_none]
592#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
593#[serde(rename_all = "camelCase")]
594#[non_exhaustive]
595pub struct NesEditHistoryCapabilities {
596 pub max_count: Option<u32>,
598 #[serde(rename = "_meta")]
604 pub meta: Option<Meta>,
605}
606
607impl NesEditHistoryCapabilities {
608 #[must_use]
609 pub fn new() -> Self {
610 Self::default()
611 }
612}
613
614#[skip_serializing_none]
616#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
617#[serde(rename_all = "camelCase")]
618#[non_exhaustive]
619pub struct NesUserActionsCapabilities {
620 pub max_count: Option<u32>,
622 #[serde(rename = "_meta")]
628 pub meta: Option<Meta>,
629}
630
631impl NesUserActionsCapabilities {
632 #[must_use]
633 pub fn new() -> Self {
634 Self::default()
635 }
636}
637
638#[skip_serializing_none]
640#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
641#[serde(rename_all = "camelCase")]
642#[non_exhaustive]
643pub struct NesOpenFilesCapabilities {
644 #[serde(rename = "_meta")]
650 pub meta: Option<Meta>,
651}
652
653impl NesOpenFilesCapabilities {
654 #[must_use]
655 pub fn new() -> Self {
656 Self::default()
657 }
658}
659
660#[skip_serializing_none]
662#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
663#[serde(rename_all = "camelCase")]
664#[non_exhaustive]
665pub struct NesDiagnosticsCapabilities {
666 #[serde(rename = "_meta")]
672 pub meta: Option<Meta>,
673}
674
675impl NesDiagnosticsCapabilities {
676 #[must_use]
677 pub fn new() -> Self {
678 Self::default()
679 }
680}
681
682#[serde_as]
686#[skip_serializing_none]
687#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
688#[serde(rename_all = "camelCase")]
689#[non_exhaustive]
690pub struct ClientNesCapabilities {
691 #[serde_as(deserialize_as = "DefaultOnError")]
693 #[schemars(extend("x-deserialize-default-on-error" = true))]
694 #[serde(default)]
695 pub jump: Option<NesJumpCapabilities>,
696 #[serde_as(deserialize_as = "DefaultOnError")]
698 #[schemars(extend("x-deserialize-default-on-error" = true))]
699 #[serde(default)]
700 pub rename: Option<NesRenameCapabilities>,
701 #[serde_as(deserialize_as = "DefaultOnError")]
703 #[schemars(extend("x-deserialize-default-on-error" = true))]
704 #[serde(default)]
705 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
706 #[serde(rename = "_meta")]
712 pub meta: Option<Meta>,
713}
714
715impl ClientNesCapabilities {
716 #[must_use]
717 pub fn new() -> Self {
718 Self::default()
719 }
720
721 #[must_use]
722 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
723 self.jump = jump.into_option();
724 self
725 }
726
727 #[must_use]
728 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
729 self.rename = rename.into_option();
730 self
731 }
732
733 #[must_use]
734 pub fn search_and_replace(
735 mut self,
736 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
737 ) -> Self {
738 self.search_and_replace = search_and_replace.into_option();
739 self
740 }
741
742 #[must_use]
748 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
749 self.meta = meta.into_option();
750 self
751 }
752}
753
754#[skip_serializing_none]
756#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
757#[serde(rename_all = "camelCase")]
758#[non_exhaustive]
759pub struct NesJumpCapabilities {
760 #[serde(rename = "_meta")]
766 pub meta: Option<Meta>,
767}
768
769impl NesJumpCapabilities {
770 #[must_use]
771 pub fn new() -> Self {
772 Self::default()
773 }
774}
775
776#[skip_serializing_none]
778#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
779#[serde(rename_all = "camelCase")]
780#[non_exhaustive]
781pub struct NesRenameCapabilities {
782 #[serde(rename = "_meta")]
788 pub meta: Option<Meta>,
789}
790
791impl NesRenameCapabilities {
792 #[must_use]
793 pub fn new() -> Self {
794 Self::default()
795 }
796}
797
798#[skip_serializing_none]
800#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
801#[serde(rename_all = "camelCase")]
802#[non_exhaustive]
803pub struct NesSearchAndReplaceCapabilities {
804 #[serde(rename = "_meta")]
810 pub meta: Option<Meta>,
811}
812
813impl NesSearchAndReplaceCapabilities {
814 #[must_use]
815 pub fn new() -> Self {
816 Self::default()
817 }
818}
819
820#[skip_serializing_none]
824#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
825#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME))]
826#[serde(rename_all = "camelCase")]
827#[non_exhaustive]
828pub struct DidOpenDocumentNotification {
829 pub session_id: SessionId,
831 pub uri: String,
833 pub language_id: String,
835 pub version: i64,
837 pub text: String,
839 #[serde(rename = "_meta")]
845 pub meta: Option<Meta>,
846}
847
848impl DidOpenDocumentNotification {
849 #[must_use]
850 pub fn new(
851 session_id: impl Into<SessionId>,
852 uri: impl Into<String>,
853 language_id: impl Into<String>,
854 version: i64,
855 text: impl Into<String>,
856 ) -> Self {
857 Self {
858 session_id: session_id.into(),
859 uri: uri.into(),
860 language_id: language_id.into(),
861 version,
862 text: text.into(),
863 meta: None,
864 }
865 }
866
867 #[must_use]
873 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
874 self.meta = meta.into_option();
875 self
876 }
877}
878
879#[skip_serializing_none]
881#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
882#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME))]
883#[serde(rename_all = "camelCase")]
884#[non_exhaustive]
885pub struct DidChangeDocumentNotification {
886 pub session_id: SessionId,
888 pub uri: String,
890 pub version: i64,
892 pub content_changes: Vec<TextDocumentContentChangeEvent>,
894 #[serde(rename = "_meta")]
900 pub meta: Option<Meta>,
901}
902
903impl DidChangeDocumentNotification {
904 #[must_use]
905 pub fn new(
906 session_id: impl Into<SessionId>,
907 uri: impl Into<String>,
908 version: i64,
909 content_changes: Vec<TextDocumentContentChangeEvent>,
910 ) -> Self {
911 Self {
912 session_id: session_id.into(),
913 uri: uri.into(),
914 version,
915 content_changes,
916 meta: None,
917 }
918 }
919
920 #[must_use]
926 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
927 self.meta = meta.into_option();
928 self
929 }
930}
931
932#[skip_serializing_none]
937#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
938#[serde(rename_all = "camelCase")]
939#[non_exhaustive]
940pub struct TextDocumentContentChangeEvent {
941 pub range: Option<Range>,
943 pub text: String,
945}
946
947impl TextDocumentContentChangeEvent {
948 #[must_use]
949 pub fn full(text: impl Into<String>) -> Self {
950 Self {
951 range: None,
952 text: text.into(),
953 }
954 }
955
956 #[must_use]
957 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
958 Self {
959 range: Some(range),
960 text: text.into(),
961 }
962 }
963}
964
965#[skip_serializing_none]
967#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
968#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME))]
969#[serde(rename_all = "camelCase")]
970#[non_exhaustive]
971pub struct DidCloseDocumentNotification {
972 pub session_id: SessionId,
974 pub uri: String,
976 #[serde(rename = "_meta")]
982 pub meta: Option<Meta>,
983}
984
985impl DidCloseDocumentNotification {
986 #[must_use]
987 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
988 Self {
989 session_id: session_id.into(),
990 uri: uri.into(),
991 meta: None,
992 }
993 }
994
995 #[must_use]
1001 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1002 self.meta = meta.into_option();
1003 self
1004 }
1005}
1006
1007#[skip_serializing_none]
1009#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1010#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_SAVE_METHOD_NAME))]
1011#[serde(rename_all = "camelCase")]
1012#[non_exhaustive]
1013pub struct DidSaveDocumentNotification {
1014 pub session_id: SessionId,
1016 pub uri: String,
1018 #[serde(rename = "_meta")]
1024 pub meta: Option<Meta>,
1025}
1026
1027impl DidSaveDocumentNotification {
1028 #[must_use]
1029 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1030 Self {
1031 session_id: session_id.into(),
1032 uri: uri.into(),
1033 meta: None,
1034 }
1035 }
1036
1037 #[must_use]
1043 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1044 self.meta = meta.into_option();
1045 self
1046 }
1047}
1048
1049#[skip_serializing_none]
1051#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1052#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME))]
1053#[serde(rename_all = "camelCase")]
1054#[non_exhaustive]
1055pub struct DidFocusDocumentNotification {
1056 pub session_id: SessionId,
1058 pub uri: String,
1060 pub version: i64,
1062 pub position: Position,
1064 pub visible_range: Range,
1066 #[serde(rename = "_meta")]
1072 pub meta: Option<Meta>,
1073}
1074
1075impl DidFocusDocumentNotification {
1076 #[must_use]
1077 pub fn new(
1078 session_id: impl Into<SessionId>,
1079 uri: impl Into<String>,
1080 version: i64,
1081 position: Position,
1082 visible_range: Range,
1083 ) -> Self {
1084 Self {
1085 session_id: session_id.into(),
1086 uri: uri.into(),
1087 version,
1088 position,
1089 visible_range,
1090 meta: None,
1091 }
1092 }
1093
1094 #[must_use]
1100 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1101 self.meta = meta.into_option();
1102 self
1103 }
1104}
1105
1106#[serde_as]
1110#[skip_serializing_none]
1111#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1112#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1113#[serde(rename_all = "camelCase")]
1114#[non_exhaustive]
1115pub struct StartNesRequest {
1116 pub workspace_uri: Option<String>,
1118 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1120 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1121 #[serde(default)]
1122 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1123 #[serde_as(deserialize_as = "DefaultOnError")]
1125 #[schemars(extend("x-deserialize-default-on-error" = true))]
1126 #[serde(default)]
1127 pub repository: Option<NesRepository>,
1128 #[serde(rename = "_meta")]
1134 pub meta: Option<Meta>,
1135}
1136
1137impl StartNesRequest {
1138 #[must_use]
1139 pub fn new() -> Self {
1140 Self {
1141 workspace_uri: None,
1142 workspace_folders: None,
1143 repository: None,
1144 meta: None,
1145 }
1146 }
1147
1148 #[must_use]
1149 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1150 self.workspace_uri = workspace_uri.into_option();
1151 self
1152 }
1153
1154 #[must_use]
1155 pub fn workspace_folders(
1156 mut self,
1157 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1158 ) -> Self {
1159 self.workspace_folders = workspace_folders.into_option();
1160 self
1161 }
1162
1163 #[must_use]
1164 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1165 self.repository = repository.into_option();
1166 self
1167 }
1168
1169 #[must_use]
1175 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1176 self.meta = meta.into_option();
1177 self
1178 }
1179}
1180
1181impl Default for StartNesRequest {
1182 fn default() -> Self {
1183 Self::new()
1184 }
1185}
1186
1187#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1189#[serde(rename_all = "camelCase")]
1190#[non_exhaustive]
1191pub struct WorkspaceFolder {
1192 pub uri: String,
1194 pub name: String,
1196}
1197
1198impl WorkspaceFolder {
1199 #[must_use]
1200 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1201 Self {
1202 uri: uri.into(),
1203 name: name.into(),
1204 }
1205 }
1206}
1207
1208#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1210#[serde(rename_all = "camelCase")]
1211#[non_exhaustive]
1212pub struct NesRepository {
1213 pub name: String,
1215 pub owner: String,
1217 pub remote_url: String,
1219}
1220
1221impl NesRepository {
1222 #[must_use]
1223 pub fn new(
1224 name: impl Into<String>,
1225 owner: impl Into<String>,
1226 remote_url: impl Into<String>,
1227 ) -> Self {
1228 Self {
1229 name: name.into(),
1230 owner: owner.into(),
1231 remote_url: remote_url.into(),
1232 }
1233 }
1234}
1235
1236#[skip_serializing_none]
1238#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1239#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1240#[serde(rename_all = "camelCase")]
1241#[non_exhaustive]
1242pub struct StartNesResponse {
1243 pub session_id: SessionId,
1245 #[serde(rename = "_meta")]
1251 pub meta: Option<Meta>,
1252}
1253
1254impl StartNesResponse {
1255 #[must_use]
1256 pub fn new(session_id: impl Into<SessionId>) -> Self {
1257 Self {
1258 session_id: session_id.into(),
1259 meta: None,
1260 }
1261 }
1262
1263 #[must_use]
1269 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1270 self.meta = meta.into_option();
1271 self
1272 }
1273}
1274
1275#[skip_serializing_none]
1282#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1283#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1284#[serde(rename_all = "camelCase")]
1285#[non_exhaustive]
1286pub struct CloseNesRequest {
1287 pub session_id: SessionId,
1289 #[serde(rename = "_meta")]
1295 pub meta: Option<Meta>,
1296}
1297
1298impl CloseNesRequest {
1299 #[must_use]
1300 pub fn new(session_id: impl Into<SessionId>) -> Self {
1301 Self {
1302 session_id: session_id.into(),
1303 meta: None,
1304 }
1305 }
1306
1307 #[must_use]
1313 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1314 self.meta = meta.into_option();
1315 self
1316 }
1317}
1318
1319#[skip_serializing_none]
1321#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1322#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1323#[serde(rename_all = "camelCase")]
1324#[non_exhaustive]
1325pub struct CloseNesResponse {
1326 #[serde(rename = "_meta")]
1332 pub meta: Option<Meta>,
1333}
1334
1335impl CloseNesResponse {
1336 #[must_use]
1337 pub fn new() -> Self {
1338 Self::default()
1339 }
1340
1341 #[must_use]
1347 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1348 self.meta = meta.into_option();
1349 self
1350 }
1351}
1352
1353#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1357#[non_exhaustive]
1358pub enum NesTriggerKind {
1359 #[serde(rename = "automatic")]
1361 Automatic,
1362 #[serde(rename = "diagnostic")]
1364 Diagnostic,
1365 #[serde(rename = "manual")]
1367 Manual,
1368}
1369
1370#[serde_as]
1372#[skip_serializing_none]
1373#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1374#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1375#[serde(rename_all = "camelCase")]
1376#[non_exhaustive]
1377pub struct SuggestNesRequest {
1378 pub session_id: SessionId,
1380 pub uri: String,
1382 pub version: i64,
1384 pub position: Position,
1386 #[serde_as(deserialize_as = "DefaultOnError")]
1388 #[schemars(extend("x-deserialize-default-on-error" = true))]
1389 #[serde(default)]
1390 pub selection: Option<Range>,
1391 pub trigger_kind: NesTriggerKind,
1393 #[serde_as(deserialize_as = "DefaultOnError")]
1395 #[schemars(extend("x-deserialize-default-on-error" = true))]
1396 #[serde(default)]
1397 pub context: Option<NesSuggestContext>,
1398 #[serde(rename = "_meta")]
1404 pub meta: Option<Meta>,
1405}
1406
1407impl SuggestNesRequest {
1408 #[must_use]
1409 pub fn new(
1410 session_id: impl Into<SessionId>,
1411 uri: impl Into<String>,
1412 version: i64,
1413 position: Position,
1414 trigger_kind: NesTriggerKind,
1415 ) -> Self {
1416 Self {
1417 session_id: session_id.into(),
1418 uri: uri.into(),
1419 version,
1420 position,
1421 selection: None,
1422 trigger_kind,
1423 context: None,
1424 meta: None,
1425 }
1426 }
1427
1428 #[must_use]
1429 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1430 self.selection = selection.into_option();
1431 self
1432 }
1433
1434 #[must_use]
1435 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1436 self.context = context.into_option();
1437 self
1438 }
1439
1440 #[must_use]
1446 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1447 self.meta = meta.into_option();
1448 self
1449 }
1450}
1451
1452#[serde_as]
1454#[skip_serializing_none]
1455#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1456#[serde(rename_all = "camelCase")]
1457#[non_exhaustive]
1458pub struct NesSuggestContext {
1459 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1461 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1462 #[serde(default)]
1463 pub recent_files: Option<Vec<NesRecentFile>>,
1464 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1466 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1467 #[serde(default)]
1468 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1469 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1471 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1472 #[serde(default)]
1473 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1474 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1476 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1477 #[serde(default)]
1478 pub user_actions: Option<Vec<NesUserAction>>,
1479 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1481 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1482 #[serde(default)]
1483 pub open_files: Option<Vec<NesOpenFile>>,
1484 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1486 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1487 #[serde(default)]
1488 pub diagnostics: Option<Vec<NesDiagnostic>>,
1489 #[serde(rename = "_meta")]
1495 pub meta: Option<Meta>,
1496}
1497
1498impl NesSuggestContext {
1499 #[must_use]
1500 pub fn new() -> Self {
1501 Self::default()
1502 }
1503
1504 #[must_use]
1505 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1506 self.recent_files = recent_files.into_option();
1507 self
1508 }
1509
1510 #[must_use]
1511 pub fn related_snippets(
1512 mut self,
1513 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1514 ) -> Self {
1515 self.related_snippets = related_snippets.into_option();
1516 self
1517 }
1518
1519 #[must_use]
1520 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1521 self.edit_history = edit_history.into_option();
1522 self
1523 }
1524
1525 #[must_use]
1526 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1527 self.user_actions = user_actions.into_option();
1528 self
1529 }
1530
1531 #[must_use]
1532 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1533 self.open_files = open_files.into_option();
1534 self
1535 }
1536
1537 #[must_use]
1538 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1539 self.diagnostics = diagnostics.into_option();
1540 self
1541 }
1542
1543 #[must_use]
1549 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1550 self.meta = meta.into_option();
1551 self
1552 }
1553}
1554
1555#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1557#[serde(rename_all = "camelCase")]
1558#[non_exhaustive]
1559pub struct NesRecentFile {
1560 pub uri: String,
1562 pub language_id: String,
1564 pub text: String,
1566}
1567
1568impl NesRecentFile {
1569 #[must_use]
1570 pub fn new(
1571 uri: impl Into<String>,
1572 language_id: impl Into<String>,
1573 text: impl Into<String>,
1574 ) -> Self {
1575 Self {
1576 uri: uri.into(),
1577 language_id: language_id.into(),
1578 text: text.into(),
1579 }
1580 }
1581}
1582
1583#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1585#[serde(rename_all = "camelCase")]
1586#[non_exhaustive]
1587pub struct NesRelatedSnippet {
1588 pub uri: String,
1590 pub excerpts: Vec<NesExcerpt>,
1592}
1593
1594impl NesRelatedSnippet {
1595 #[must_use]
1596 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
1597 Self {
1598 uri: uri.into(),
1599 excerpts,
1600 }
1601 }
1602}
1603
1604#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1606#[serde(rename_all = "camelCase")]
1607#[non_exhaustive]
1608pub struct NesExcerpt {
1609 pub start_line: u32,
1611 pub end_line: u32,
1613 pub text: String,
1615}
1616
1617impl NesExcerpt {
1618 #[must_use]
1619 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
1620 Self {
1621 start_line,
1622 end_line,
1623 text: text.into(),
1624 }
1625 }
1626}
1627
1628#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1630#[serde(rename_all = "camelCase")]
1631#[non_exhaustive]
1632pub struct NesEditHistoryEntry {
1633 pub uri: String,
1635 pub diff: String,
1637}
1638
1639impl NesEditHistoryEntry {
1640 #[must_use]
1641 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
1642 Self {
1643 uri: uri.into(),
1644 diff: diff.into(),
1645 }
1646 }
1647}
1648
1649#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1651#[serde(rename_all = "camelCase")]
1652#[non_exhaustive]
1653pub struct NesUserAction {
1654 pub action: String,
1656 pub uri: String,
1658 pub position: Position,
1660 pub timestamp_ms: u64,
1662}
1663
1664impl NesUserAction {
1665 #[must_use]
1666 pub fn new(
1667 action: impl Into<String>,
1668 uri: impl Into<String>,
1669 position: Position,
1670 timestamp_ms: u64,
1671 ) -> Self {
1672 Self {
1673 action: action.into(),
1674 uri: uri.into(),
1675 position,
1676 timestamp_ms,
1677 }
1678 }
1679}
1680
1681#[serde_as]
1683#[skip_serializing_none]
1684#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1685#[serde(rename_all = "camelCase")]
1686#[non_exhaustive]
1687pub struct NesOpenFile {
1688 pub uri: String,
1690 pub language_id: String,
1692 #[serde_as(deserialize_as = "DefaultOnError")]
1694 #[schemars(extend("x-deserialize-default-on-error" = true))]
1695 #[serde(default)]
1696 pub visible_range: Option<Range>,
1697 #[serde_as(deserialize_as = "DefaultOnError")]
1699 #[schemars(extend("x-deserialize-default-on-error" = true))]
1700 #[serde(default)]
1701 pub last_focused_ms: Option<u64>,
1702}
1703
1704impl NesOpenFile {
1705 #[must_use]
1706 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
1707 Self {
1708 uri: uri.into(),
1709 language_id: language_id.into(),
1710 visible_range: None,
1711 last_focused_ms: None,
1712 }
1713 }
1714
1715 #[must_use]
1716 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
1717 self.visible_range = visible_range.into_option();
1718 self
1719 }
1720
1721 #[must_use]
1722 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
1723 self.last_focused_ms = last_focused_ms.into_option();
1724 self
1725 }
1726}
1727
1728#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1730#[serde(rename_all = "camelCase")]
1731#[non_exhaustive]
1732pub struct NesDiagnostic {
1733 pub uri: String,
1735 pub range: Range,
1737 pub severity: NesDiagnosticSeverity,
1739 pub message: String,
1741}
1742
1743impl NesDiagnostic {
1744 #[must_use]
1745 pub fn new(
1746 uri: impl Into<String>,
1747 range: Range,
1748 severity: NesDiagnosticSeverity,
1749 message: impl Into<String>,
1750 ) -> Self {
1751 Self {
1752 uri: uri.into(),
1753 range,
1754 severity,
1755 message: message.into(),
1756 }
1757 }
1758}
1759
1760#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1762#[non_exhaustive]
1763pub enum NesDiagnosticSeverity {
1764 #[serde(rename = "error")]
1766 Error,
1767 #[serde(rename = "warning")]
1769 Warning,
1770 #[serde(rename = "information")]
1772 Information,
1773 #[serde(rename = "hint")]
1775 Hint,
1776}
1777
1778#[serde_as]
1782#[skip_serializing_none]
1783#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1784#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1785#[serde(rename_all = "camelCase")]
1786#[non_exhaustive]
1787pub struct SuggestNesResponse {
1788 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
1790 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1791 pub suggestions: Vec<NesSuggestion>,
1792 #[serde(rename = "_meta")]
1798 pub meta: Option<Meta>,
1799}
1800
1801impl SuggestNesResponse {
1802 #[must_use]
1803 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
1804 Self {
1805 suggestions,
1806 meta: None,
1807 }
1808 }
1809
1810 #[must_use]
1816 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1817 self.meta = meta.into_option();
1818 self
1819 }
1820}
1821
1822#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1824#[serde(tag = "kind", rename_all = "camelCase")]
1825#[schemars(extend("discriminator" = {"propertyName": "kind"}))]
1826#[non_exhaustive]
1827pub enum NesSuggestion {
1828 Edit(NesEditSuggestion),
1830 Jump(NesJumpSuggestion),
1832 Rename(NesRenameSuggestion),
1834 SearchAndReplace(NesSearchAndReplaceSuggestion),
1836}
1837
1838#[serde_as]
1840#[skip_serializing_none]
1841#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1842#[serde(rename_all = "camelCase")]
1843#[non_exhaustive]
1844pub struct NesEditSuggestion {
1845 pub id: String,
1847 pub uri: String,
1849 pub edits: Vec<NesTextEdit>,
1851 #[serde_as(deserialize_as = "DefaultOnError")]
1853 #[schemars(extend("x-deserialize-default-on-error" = true))]
1854 #[serde(default)]
1855 pub cursor_position: Option<Position>,
1856}
1857
1858impl NesEditSuggestion {
1859 #[must_use]
1860 pub fn new(id: impl Into<String>, uri: impl Into<String>, edits: Vec<NesTextEdit>) -> Self {
1861 Self {
1862 id: id.into(),
1863 uri: uri.into(),
1864 edits,
1865 cursor_position: None,
1866 }
1867 }
1868
1869 #[must_use]
1870 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
1871 self.cursor_position = cursor_position.into_option();
1872 self
1873 }
1874}
1875
1876#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1878#[serde(rename_all = "camelCase")]
1879#[non_exhaustive]
1880pub struct NesTextEdit {
1881 pub range: Range,
1883 pub new_text: String,
1885}
1886
1887impl NesTextEdit {
1888 #[must_use]
1889 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
1890 Self {
1891 range,
1892 new_text: new_text.into(),
1893 }
1894 }
1895}
1896
1897#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1899#[serde(rename_all = "camelCase")]
1900#[non_exhaustive]
1901pub struct NesJumpSuggestion {
1902 pub id: String,
1904 pub uri: String,
1906 pub position: Position,
1908}
1909
1910impl NesJumpSuggestion {
1911 #[must_use]
1912 pub fn new(id: impl Into<String>, uri: impl Into<String>, position: Position) -> Self {
1913 Self {
1914 id: id.into(),
1915 uri: uri.into(),
1916 position,
1917 }
1918 }
1919}
1920
1921#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1923#[serde(rename_all = "camelCase")]
1924#[non_exhaustive]
1925pub struct NesRenameSuggestion {
1926 pub id: String,
1928 pub uri: String,
1930 pub position: Position,
1932 pub new_name: String,
1934}
1935
1936impl NesRenameSuggestion {
1937 #[must_use]
1938 pub fn new(
1939 id: impl Into<String>,
1940 uri: impl Into<String>,
1941 position: Position,
1942 new_name: impl Into<String>,
1943 ) -> Self {
1944 Self {
1945 id: id.into(),
1946 uri: uri.into(),
1947 position,
1948 new_name: new_name.into(),
1949 }
1950 }
1951}
1952
1953#[skip_serializing_none]
1955#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1956#[serde(rename_all = "camelCase")]
1957#[non_exhaustive]
1958pub struct NesSearchAndReplaceSuggestion {
1959 pub id: String,
1961 pub uri: String,
1963 pub search: String,
1965 pub replace: String,
1967 pub is_regex: Option<bool>,
1969}
1970
1971impl NesSearchAndReplaceSuggestion {
1972 #[must_use]
1973 pub fn new(
1974 id: impl Into<String>,
1975 uri: impl Into<String>,
1976 search: impl Into<String>,
1977 replace: impl Into<String>,
1978 ) -> Self {
1979 Self {
1980 id: id.into(),
1981 uri: uri.into(),
1982 search: search.into(),
1983 replace: replace.into(),
1984 is_regex: None,
1985 }
1986 }
1987
1988 #[must_use]
1989 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
1990 self.is_regex = is_regex.into_option();
1991 self
1992 }
1993}
1994
1995#[skip_serializing_none]
1999#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2000#[schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME))]
2001#[serde(rename_all = "camelCase")]
2002#[non_exhaustive]
2003pub struct AcceptNesNotification {
2004 pub session_id: SessionId,
2006 pub id: String,
2008 #[serde(rename = "_meta")]
2014 pub meta: Option<Meta>,
2015}
2016
2017impl AcceptNesNotification {
2018 #[must_use]
2019 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2020 Self {
2021 session_id: session_id.into(),
2022 id: id.into(),
2023 meta: None,
2024 }
2025 }
2026
2027 #[must_use]
2033 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2034 self.meta = meta.into_option();
2035 self
2036 }
2037}
2038
2039#[serde_as]
2041#[skip_serializing_none]
2042#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2043#[schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME))]
2044#[serde(rename_all = "camelCase")]
2045#[non_exhaustive]
2046pub struct RejectNesNotification {
2047 pub session_id: SessionId,
2049 pub id: String,
2051 #[serde_as(deserialize_as = "DefaultOnError")]
2053 #[schemars(extend("x-deserialize-default-on-error" = true))]
2054 #[serde(default)]
2055 pub reason: Option<NesRejectReason>,
2056 #[serde(rename = "_meta")]
2062 pub meta: Option<Meta>,
2063}
2064
2065impl RejectNesNotification {
2066 #[must_use]
2067 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2068 Self {
2069 session_id: session_id.into(),
2070 id: id.into(),
2071 reason: None,
2072 meta: None,
2073 }
2074 }
2075
2076 #[must_use]
2077 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2078 self.reason = reason.into_option();
2079 self
2080 }
2081
2082 #[must_use]
2088 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2089 self.meta = meta.into_option();
2090 self
2091 }
2092}
2093
2094#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2096#[non_exhaustive]
2097pub enum NesRejectReason {
2098 #[serde(rename = "rejected")]
2100 Rejected,
2101 #[serde(rename = "ignored")]
2103 Ignored,
2104 #[serde(rename = "replaced")]
2106 Replaced,
2107 #[serde(rename = "cancelled")]
2109 Cancelled,
2110}
2111
2112#[cfg(test)]
2113mod tests {
2114 use super::*;
2115 use serde_json::json;
2116
2117 #[test]
2118 fn test_position_encoding_kind_serialization() {
2119 assert_eq!(
2120 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2121 json!("utf-16")
2122 );
2123 assert_eq!(
2124 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2125 json!("utf-32")
2126 );
2127 assert_eq!(
2128 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2129 json!("utf-8")
2130 );
2131
2132 assert_eq!(
2133 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2134 PositionEncodingKind::Utf16
2135 );
2136 assert_eq!(
2137 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2138 PositionEncodingKind::Utf32
2139 );
2140 assert_eq!(
2141 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2142 PositionEncodingKind::Utf8
2143 );
2144 }
2145
2146 #[test]
2147 fn test_agent_nes_capabilities_serialization() {
2148 let caps = NesCapabilities::new()
2149 .events(
2150 NesEventCapabilities::new().document(
2151 NesDocumentEventCapabilities::new()
2152 .did_open(NesDocumentDidOpenCapabilities::default())
2153 .did_change(NesDocumentDidChangeCapabilities::new(
2154 TextDocumentSyncKind::Incremental,
2155 ))
2156 .did_close(NesDocumentDidCloseCapabilities::default())
2157 .did_save(NesDocumentDidSaveCapabilities::default())
2158 .did_focus(NesDocumentDidFocusCapabilities::default()),
2159 ),
2160 )
2161 .context(
2162 NesContextCapabilities::new()
2163 .recent_files(NesRecentFilesCapabilities {
2164 max_count: Some(10),
2165 meta: None,
2166 })
2167 .related_snippets(NesRelatedSnippetsCapabilities::default())
2168 .edit_history(NesEditHistoryCapabilities {
2169 max_count: Some(6),
2170 meta: None,
2171 })
2172 .user_actions(NesUserActionsCapabilities {
2173 max_count: Some(16),
2174 meta: None,
2175 })
2176 .open_files(NesOpenFilesCapabilities::default())
2177 .diagnostics(NesDiagnosticsCapabilities::default()),
2178 );
2179
2180 let json = serde_json::to_value(&caps).unwrap();
2181 assert_eq!(
2182 json,
2183 json!({
2184 "events": {
2185 "document": {
2186 "didOpen": {},
2187 "didChange": {
2188 "syncKind": "incremental"
2189 },
2190 "didClose": {},
2191 "didSave": {},
2192 "didFocus": {}
2193 }
2194 },
2195 "context": {
2196 "recentFiles": {
2197 "maxCount": 10
2198 },
2199 "relatedSnippets": {},
2200 "editHistory": {
2201 "maxCount": 6
2202 },
2203 "userActions": {
2204 "maxCount": 16
2205 },
2206 "openFiles": {},
2207 "diagnostics": {}
2208 }
2209 })
2210 );
2211
2212 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
2214 assert_eq!(deserialized, caps);
2215 }
2216
2217 #[test]
2218 fn test_client_nes_capabilities_serialization() {
2219 let caps = ClientNesCapabilities::new()
2220 .jump(NesJumpCapabilities::default())
2221 .rename(NesRenameCapabilities::default())
2222 .search_and_replace(NesSearchAndReplaceCapabilities::default());
2223
2224 let json = serde_json::to_value(&caps).unwrap();
2225 assert_eq!(
2226 json,
2227 json!({
2228 "jump": {},
2229 "rename": {},
2230 "searchAndReplace": {}
2231 })
2232 );
2233
2234 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
2235 assert_eq!(deserialized, caps);
2236 }
2237
2238 #[test]
2239 fn test_document_did_open_serialization() {
2240 let notification = DidOpenDocumentNotification::new(
2241 "session_123",
2242 "file:///path/to/file.rs",
2243 "rust",
2244 1,
2245 "fn main() {\n println!(\"hello\");\n}\n",
2246 );
2247
2248 let json = serde_json::to_value(¬ification).unwrap();
2249 assert_eq!(
2250 json,
2251 json!({
2252 "sessionId": "session_123",
2253 "uri": "file:///path/to/file.rs",
2254 "languageId": "rust",
2255 "version": 1,
2256 "text": "fn main() {\n println!(\"hello\");\n}\n"
2257 })
2258 );
2259
2260 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
2261 assert_eq!(deserialized, notification);
2262 }
2263
2264 #[test]
2265 fn test_document_did_change_incremental_serialization() {
2266 let notification = DidChangeDocumentNotification::new(
2267 "session_123",
2268 "file:///path/to/file.rs",
2269 2,
2270 vec![TextDocumentContentChangeEvent::incremental(
2271 Range::new(Position::new(1, 4), Position::new(1, 4)),
2272 "let x = 42;\n ",
2273 )],
2274 );
2275
2276 let json = serde_json::to_value(¬ification).unwrap();
2277 assert_eq!(
2278 json,
2279 json!({
2280 "sessionId": "session_123",
2281 "uri": "file:///path/to/file.rs",
2282 "version": 2,
2283 "contentChanges": [
2284 {
2285 "range": {
2286 "start": { "line": 1, "character": 4 },
2287 "end": { "line": 1, "character": 4 }
2288 },
2289 "text": "let x = 42;\n "
2290 }
2291 ]
2292 })
2293 );
2294 }
2295
2296 #[test]
2297 fn test_document_did_change_full_serialization() {
2298 let notification = DidChangeDocumentNotification::new(
2299 "session_123",
2300 "file:///path/to/file.rs",
2301 2,
2302 vec![TextDocumentContentChangeEvent::full(
2303 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
2304 )],
2305 );
2306
2307 let json = serde_json::to_value(¬ification).unwrap();
2308 assert_eq!(
2309 json,
2310 json!({
2311 "sessionId": "session_123",
2312 "uri": "file:///path/to/file.rs",
2313 "version": 2,
2314 "contentChanges": [
2315 {
2316 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
2317 }
2318 ]
2319 })
2320 );
2321 }
2322
2323 #[test]
2324 fn test_document_did_close_serialization() {
2325 let notification =
2326 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
2327 let json = serde_json::to_value(¬ification).unwrap();
2328 assert_eq!(
2329 json,
2330 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2331 );
2332 }
2333
2334 #[test]
2335 fn test_document_did_save_serialization() {
2336 let notification =
2337 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
2338 let json = serde_json::to_value(¬ification).unwrap();
2339 assert_eq!(
2340 json,
2341 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2342 );
2343 }
2344
2345 #[test]
2346 fn test_document_did_focus_serialization() {
2347 let notification = DidFocusDocumentNotification::new(
2348 "session_123",
2349 "file:///path/to/file.rs",
2350 2,
2351 Position::new(5, 12),
2352 Range::new(Position::new(0, 0), Position::new(45, 0)),
2353 );
2354
2355 let json = serde_json::to_value(¬ification).unwrap();
2356 assert_eq!(
2357 json,
2358 json!({
2359 "sessionId": "session_123",
2360 "uri": "file:///path/to/file.rs",
2361 "version": 2,
2362 "position": { "line": 5, "character": 12 },
2363 "visibleRange": {
2364 "start": { "line": 0, "character": 0 },
2365 "end": { "line": 45, "character": 0 }
2366 }
2367 })
2368 );
2369 }
2370
2371 #[test]
2372 fn test_nes_suggestion_edit_serialization() {
2373 let suggestion = NesSuggestion::Edit(
2374 NesEditSuggestion::new(
2375 "sugg_001",
2376 "file:///path/to/other_file.rs",
2377 vec![NesTextEdit::new(
2378 Range::new(Position::new(5, 0), Position::new(5, 10)),
2379 "let result = helper();",
2380 )],
2381 )
2382 .cursor_position(Position::new(5, 22)),
2383 );
2384
2385 let json = serde_json::to_value(&suggestion).unwrap();
2386 assert_eq!(
2387 json,
2388 json!({
2389 "kind": "edit",
2390 "id": "sugg_001",
2391 "uri": "file:///path/to/other_file.rs",
2392 "edits": [
2393 {
2394 "range": {
2395 "start": { "line": 5, "character": 0 },
2396 "end": { "line": 5, "character": 10 }
2397 },
2398 "newText": "let result = helper();"
2399 }
2400 ],
2401 "cursorPosition": { "line": 5, "character": 22 }
2402 })
2403 );
2404
2405 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2406 assert_eq!(deserialized, suggestion);
2407 }
2408
2409 #[test]
2410 fn test_nes_suggestion_jump_serialization() {
2411 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
2412 "sugg_002",
2413 "file:///path/to/other_file.rs",
2414 Position::new(15, 4),
2415 ));
2416
2417 let json = serde_json::to_value(&suggestion).unwrap();
2418 assert_eq!(
2419 json,
2420 json!({
2421 "kind": "jump",
2422 "id": "sugg_002",
2423 "uri": "file:///path/to/other_file.rs",
2424 "position": { "line": 15, "character": 4 }
2425 })
2426 );
2427
2428 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2429 assert_eq!(deserialized, suggestion);
2430 }
2431
2432 #[test]
2433 fn test_nes_suggestion_rename_serialization() {
2434 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
2435 "sugg_003",
2436 "file:///path/to/file.rs",
2437 Position::new(5, 10),
2438 "calculateTotal",
2439 ));
2440
2441 let json = serde_json::to_value(&suggestion).unwrap();
2442 assert_eq!(
2443 json,
2444 json!({
2445 "kind": "rename",
2446 "id": "sugg_003",
2447 "uri": "file:///path/to/file.rs",
2448 "position": { "line": 5, "character": 10 },
2449 "newName": "calculateTotal"
2450 })
2451 );
2452
2453 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2454 assert_eq!(deserialized, suggestion);
2455 }
2456
2457 #[test]
2458 fn test_nes_suggestion_search_and_replace_serialization() {
2459 let suggestion = NesSuggestion::SearchAndReplace(
2460 NesSearchAndReplaceSuggestion::new(
2461 "sugg_004",
2462 "file:///path/to/file.rs",
2463 "oldFunction",
2464 "newFunction",
2465 )
2466 .is_regex(false),
2467 );
2468
2469 let json = serde_json::to_value(&suggestion).unwrap();
2470 assert_eq!(
2471 json,
2472 json!({
2473 "kind": "searchAndReplace",
2474 "id": "sugg_004",
2475 "uri": "file:///path/to/file.rs",
2476 "search": "oldFunction",
2477 "replace": "newFunction",
2478 "isRegex": false
2479 })
2480 );
2481
2482 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2483 assert_eq!(deserialized, suggestion);
2484 }
2485
2486 #[test]
2487 fn test_nes_start_request_serialization() {
2488 let request = StartNesRequest::new()
2489 .workspace_uri("file:///Users/alice/projects/my-app")
2490 .workspace_folders(vec![WorkspaceFolder::new(
2491 "file:///Users/alice/projects/my-app",
2492 "my-app",
2493 )])
2494 .repository(NesRepository::new(
2495 "my-app",
2496 "alice",
2497 "https://github.com/alice/my-app.git",
2498 ));
2499
2500 let json = serde_json::to_value(&request).unwrap();
2501 assert_eq!(
2502 json,
2503 json!({
2504 "workspaceUri": "file:///Users/alice/projects/my-app",
2505 "workspaceFolders": [
2506 {
2507 "uri": "file:///Users/alice/projects/my-app",
2508 "name": "my-app"
2509 }
2510 ],
2511 "repository": {
2512 "name": "my-app",
2513 "owner": "alice",
2514 "remoteUrl": "https://github.com/alice/my-app.git"
2515 }
2516 })
2517 );
2518 }
2519
2520 #[test]
2521 fn test_nes_start_response_serialization() {
2522 let response = StartNesResponse::new("session_abc123");
2523 let json = serde_json::to_value(&response).unwrap();
2524 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
2525 }
2526
2527 #[test]
2528 fn test_nes_trigger_kind_serialization() {
2529 assert_eq!(
2530 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
2531 json!("automatic")
2532 );
2533 assert_eq!(
2534 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
2535 json!("diagnostic")
2536 );
2537 assert_eq!(
2538 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
2539 json!("manual")
2540 );
2541 }
2542
2543 #[test]
2544 fn test_nes_reject_reason_serialization() {
2545 assert_eq!(
2546 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
2547 json!("rejected")
2548 );
2549 assert_eq!(
2550 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
2551 json!("ignored")
2552 );
2553 assert_eq!(
2554 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
2555 json!("replaced")
2556 );
2557 assert_eq!(
2558 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
2559 json!("cancelled")
2560 );
2561 }
2562
2563 #[test]
2564 fn test_nes_accept_notification_serialization() {
2565 let notification = AcceptNesNotification::new("session_123", "sugg_001");
2566 let json = serde_json::to_value(¬ification).unwrap();
2567 assert_eq!(
2568 json,
2569 json!({ "sessionId": "session_123", "id": "sugg_001" })
2570 );
2571 }
2572
2573 #[test]
2574 fn test_nes_reject_notification_serialization() {
2575 let notification =
2576 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
2577 let json = serde_json::to_value(¬ification).unwrap();
2578 assert_eq!(
2579 json,
2580 json!({ "sessionId": "session_123", "id": "sugg_001", "reason": "rejected" })
2581 );
2582 }
2583
2584 #[test]
2585 fn test_nes_suggest_request_with_context_serialization() {
2586 let request = SuggestNesRequest::new(
2587 "session_123",
2588 "file:///path/to/file.rs",
2589 2,
2590 Position::new(5, 12),
2591 NesTriggerKind::Automatic,
2592 )
2593 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
2594 .context(
2595 NesSuggestContext::new()
2596 .recent_files(vec![NesRecentFile::new(
2597 "file:///path/to/utils.rs",
2598 "rust",
2599 "pub fn helper() -> i32 { 42 }\n",
2600 )])
2601 .diagnostics(vec![NesDiagnostic::new(
2602 "file:///path/to/file.rs",
2603 Range::new(Position::new(5, 0), Position::new(5, 10)),
2604 NesDiagnosticSeverity::Error,
2605 "cannot find value `foo` in this scope",
2606 )]),
2607 );
2608
2609 let json = serde_json::to_value(&request).unwrap();
2610 assert_eq!(json["sessionId"], "session_123");
2611 assert_eq!(json["uri"], "file:///path/to/file.rs");
2612 assert_eq!(json["version"], 2);
2613 assert_eq!(json["triggerKind"], "automatic");
2614 assert_eq!(
2615 json["context"]["recentFiles"][0]["uri"],
2616 "file:///path/to/utils.rs"
2617 );
2618 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
2619 }
2620
2621 #[test]
2622 fn test_text_document_sync_kind_serialization() {
2623 assert_eq!(
2624 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
2625 json!("full")
2626 );
2627 assert_eq!(
2628 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
2629 json!("incremental")
2630 );
2631 }
2632
2633 #[test]
2634 fn test_document_did_change_capabilities_requires_sync_kind() {
2635 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
2636 }
2637
2638 #[test]
2639 fn test_nes_suggest_response_serialization() {
2640 let response = SuggestNesResponse::new(vec![
2641 NesSuggestion::Edit(NesEditSuggestion::new(
2642 "sugg_001",
2643 "file:///path/to/file.rs",
2644 vec![NesTextEdit::new(
2645 Range::new(Position::new(5, 0), Position::new(5, 10)),
2646 "let result = helper();",
2647 )],
2648 )),
2649 NesSuggestion::Jump(NesJumpSuggestion::new(
2650 "sugg_002",
2651 "file:///path/to/other.rs",
2652 Position::new(10, 0),
2653 )),
2654 ]);
2655
2656 let json = serde_json::to_value(&response).unwrap();
2657 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
2658 assert_eq!(json["suggestions"][0]["kind"], "edit");
2659 assert_eq!(json["suggestions"][1]["kind"], "jump");
2660 }
2661}