1 use hir::{AsAssocItem, HasVisibility, ModuleDef, Visibility};
2 use ide_db::assists::{AssistId, AssistKind};
3 use itertools::Itertools;
4 use stdx::{format_to, to_lower_snake_case};
6 algo::skip_whitespace_token,
7 ast::{self, edit::IndentLevel, HasDocComments, HasName},
8 match_ast, AstNode, AstToken,
11 use crate::assist_context::{AssistContext, Assists};
13 // Assist: generate_documentation_template
15 // Adds a documentation template above a function definition / declaration.
20 // pub unsafe fn set_len$0(&mut self, len: usize) -> Result<(), std::io::Error> {
29 // /// Sets the length of this [`S`].
33 // /// This function will return an error if .
38 // pub unsafe fn set_len(&mut self, len: usize) -> Result<(), std::io::Error> {
43 pub(crate) fn generate_documentation_template(
45 ctx: &AssistContext<'_>,
47 let name = ctx.find_node_at_offset::<ast::Name>()?;
48 let ast_func = name.syntax().parent().and_then(ast::Fn::cast)?;
49 if is_in_trait_impl(&ast_func, ctx) || ast_func.doc_comments().next().is_some() {
53 let parent_syntax = ast_func.syntax();
54 let text_range = parent_syntax.text_range();
55 let indent_level = IndentLevel::from_node(parent_syntax);
58 AssistId("generate_documentation_template", AssistKind::Generate),
59 "Generate a documentation template",
62 // Introduction / short function description before the sections
63 let mut doc_lines = vec![introduction_builder(&ast_func, ctx).unwrap_or(".".into())];
64 // Then come the sections
65 for section_builder in [panics_builder, errors_builder, safety_builder] {
66 if let Some(mut lines) = section_builder(&ast_func) {
67 doc_lines.push("".into());
68 doc_lines.append(&mut lines);
71 builder.insert(text_range.start(), documentation_from_lines(doc_lines, indent_level));
76 // Assist: generate_doc_example
78 // Generates a rustdoc example when editing an item's documentation.
81 // /// Adds two numbers.$0
82 // pub fn add(a: i32, b: i32) -> i32 { a + b }
86 // /// Adds two numbers.
93 // /// assert_eq!(add(a, b), );
95 // pub fn add(a: i32, b: i32) -> i32 { a + b }
97 pub(crate) fn generate_doc_example(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
98 let tok: ast::Comment = ctx.find_token_at_offset()?;
99 let node = tok.syntax().parent()?;
101 ast::AnyHasDocComments::cast(node.clone())?.doc_comments().last()?.syntax().clone();
102 let next_token = skip_whitespace_token(last_doc_token.next_token()?, syntax::Direction::Next)?;
104 let example = match_ast! {
106 ast::Fn(it) => make_example_for_fn(&it, ctx)?,
111 let mut lines = string_vec_from(&["", "# Examples", "", "```"]);
112 lines.extend(example.lines().map(String::from));
113 lines.push("```".into());
114 let indent_level = IndentLevel::from_node(&node);
117 AssistId("generate_doc_example", AssistKind::Generate),
118 "Generate a documentation example",
122 next_token.text_range().start(),
123 documentation_from_lines(lines, indent_level),
129 fn make_example_for_fn(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<String> {
130 if !is_public(ast_func, ctx)? {
131 // Doctests for private items can't actually name the item, so they're pretty useless.
135 if is_in_trait_def(ast_func, ctx) {
136 // This is not yet implemented.
140 let mut example = String::new();
142 let is_unsafe = ast_func.unsafe_token().is_some();
143 let param_list = ast_func.param_list()?;
144 let ref_mut_params = ref_mut_params(¶m_list);
145 let self_name = self_name(ast_func);
147 format_to!(example, "use {};\n\n", build_path(ast_func, ctx)?);
148 if let Some(self_name) = &self_name {
149 if let Some(mtbl) = is_ref_mut_self(ast_func) {
150 let mtbl = if mtbl == true { " mut" } else { "" };
151 format_to!(example, "let{} {} = ;\n", mtbl, self_name);
154 for param_name in &ref_mut_params {
155 format_to!(example, "let mut {} = ;\n", param_name);
157 // Call the function, check result
158 let function_call = function_call(ast_func, ¶m_list, self_name.as_deref(), is_unsafe)?;
159 if returns_a_value(ast_func, ctx) {
160 if count_parameters(¶m_list) < 3 {
161 format_to!(example, "assert_eq!({}, );\n", function_call);
163 format_to!(example, "let result = {};\n", function_call);
164 example.push_str("assert_eq!(result, );\n");
167 format_to!(example, "{};\n", function_call);
169 // Check the mutated values
170 if is_ref_mut_self(ast_func) == Some(true) {
171 format_to!(example, "assert_eq!({}, );", self_name?);
173 for param_name in &ref_mut_params {
174 format_to!(example, "assert_eq!({}, );", param_name);
179 fn introduction_builder(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<String> {
180 let hir_func = ctx.sema.to_def(ast_func)?;
181 let container = hir_func.as_assoc_item(ctx.db())?.container(ctx.db());
182 if let hir::AssocItemContainer::Impl(imp) = container {
183 let ret_ty = hir_func.ret_type(ctx.db());
184 let self_ty = imp.self_ty(ctx.db());
185 let name = ast_func.name()?.to_string();
186 let linkable_self_ty = self_type_without_lifetimes(ast_func);
187 let linkable_self_ty = linkable_self_ty.as_deref();
189 let intro_for_new = || {
190 let is_new = name == "new";
191 if is_new && ret_ty == self_ty {
192 Some(format!("Creates a new [`{}`].", linkable_self_ty?))
198 let intro_for_getter = || match (
199 hir_func.self_param(ctx.sema.db),
200 &*hir_func.params_without_self(ctx.sema.db),
202 (Some(self_param), []) if self_param.access(ctx.sema.db) != hir::Access::Owned => {
203 if name.starts_with("as_") || name.starts_with("to_") || name == "get" {
206 let mut what = name.trim_end_matches("_mut").replace('_', " ");
208 what = "length".into()
210 let reference = if ret_ty.is_mutable_reference() {
211 " a mutable reference to"
212 } else if ret_ty.is_reference() {
217 Some(format!("Returns{reference} the {what} of this [`{}`].", linkable_self_ty?))
222 let intro_for_setter = || {
223 if !name.starts_with("set_") {
227 let mut what = name.trim_start_matches("set_").replace('_', " ");
229 what = "length".into()
231 Some(format!("Sets the {what} of this [`{}`].", linkable_self_ty?))
234 if let Some(intro) = intro_for_new() {
237 if let Some(intro) = intro_for_getter() {
240 if let Some(intro) = intro_for_setter() {
247 /// Builds an optional `# Panics` section
248 fn panics_builder(ast_func: &ast::Fn) -> Option<Vec<String>> {
249 match can_panic(ast_func) {
250 Some(true) => Some(string_vec_from(&["# Panics", "", "Panics if ."])),
255 /// Builds an optional `# Errors` section
256 fn errors_builder(ast_func: &ast::Fn) -> Option<Vec<String>> {
257 match return_type(ast_func)?.to_string().contains("Result") {
258 true => Some(string_vec_from(&["# Errors", "", "This function will return an error if ."])),
263 /// Builds an optional `# Safety` section
264 fn safety_builder(ast_func: &ast::Fn) -> Option<Vec<String>> {
265 let is_unsafe = ast_func.unsafe_token().is_some();
267 true => Some(string_vec_from(&["# Safety", "", "."])),
272 /// Checks if the function is public / exported
273 fn is_public(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<bool> {
274 let hir_func = ctx.sema.to_def(ast_func)?;
276 hir_func.visibility(ctx.db()) == Visibility::Public
277 && all_parent_mods_public(&hir_func, ctx),
281 /// Checks that all parent modules of the function are public / exported
282 fn all_parent_mods_public(hir_func: &hir::Function, ctx: &AssistContext<'_>) -> bool {
283 let mut module = hir_func.module(ctx.db());
285 if let Some(parent) = module.parent(ctx.db()) {
286 match ModuleDef::from(module).visibility(ctx.db()) {
287 Visibility::Public => module = parent,
296 /// Returns the name of the current crate
297 fn crate_name(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<String> {
298 let krate = ctx.sema.scope(ast_func.syntax())?.krate();
299 Some(krate.display_name(ctx.db())?.to_string())
302 /// `None` if function without a body; some bool to guess if function can panic
303 fn can_panic(ast_func: &ast::Fn) -> Option<bool> {
304 let body = ast_func.body()?.to_string();
305 let can_panic = body.contains("panic!(")
306 // FIXME it would be better to not match `debug_assert*!` macro invocations
307 || body.contains("assert!(")
308 || body.contains(".unwrap()")
309 || body.contains(".expect(");
313 /// Helper function to get the name that should be given to `self` arguments
314 fn self_name(ast_func: &ast::Fn) -> Option<String> {
315 self_partial_type(ast_func).map(|name| to_lower_snake_case(&name))
318 /// Heper function to get the name of the type of `self`
319 fn self_type(ast_func: &ast::Fn) -> Option<ast::Type> {
320 ast_func.syntax().ancestors().find_map(ast::Impl::cast).and_then(|i| i.self_ty())
323 /// Output the real name of `Self` like `MyType<T>`, without the lifetimes.
324 fn self_type_without_lifetimes(ast_func: &ast::Fn) -> Option<String> {
325 let path_segment = match self_type(ast_func)? {
326 ast::Type::PathType(path_type) => path_type.path()?.segment()?,
329 let mut name = path_segment.name_ref()?.to_string();
330 let generics = path_segment.generic_arg_list().into_iter().flat_map(|list| {
332 .filter(|generic| matches!(generic, ast::GenericArg::TypeArg(_)))
333 .map(|generic| generic.to_string())
335 let generics: String = generics.format(", ").to_string();
336 if !generics.is_empty() {
338 name.push_str(&generics);
344 /// Heper function to get the name of the type of `self` without generic arguments
345 fn self_partial_type(ast_func: &ast::Fn) -> Option<String> {
346 let mut self_type = self_type(ast_func)?.to_string();
347 if let Some(idx) = self_type.find(|c| ['<', ' '].contains(&c)) {
348 self_type.truncate(idx);
353 /// Helper function to determine if the function is in a trait implementation
354 fn is_in_trait_impl(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> bool {
357 .and_then(|hir_func| hir_func.as_assoc_item(ctx.db()))
358 .and_then(|assoc_item| assoc_item.containing_trait_impl(ctx.db()))
362 /// Helper function to determine if the function definition is in a trait definition
363 fn is_in_trait_def(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> bool {
366 .and_then(|hir_func| hir_func.as_assoc_item(ctx.db()))
367 .and_then(|assoc_item| assoc_item.containing_trait(ctx.db()))
371 /// Returns `None` if no `self` at all, `Some(true)` if there is `&mut self` else `Some(false)`
372 fn is_ref_mut_self(ast_func: &ast::Fn) -> Option<bool> {
373 let self_param = ast_func.param_list()?.self_param()?;
374 Some(self_param.mut_token().is_some() && self_param.amp_token().is_some())
377 /// Helper function to determine if a parameter is `&mut`
378 fn is_a_ref_mut_param(param: &ast::Param) -> bool {
380 Some(ast::Type::RefType(param_ref)) => param_ref.mut_token().is_some(),
385 /// Helper function to build the list of `&mut` parameters
386 fn ref_mut_params(param_list: &ast::ParamList) -> Vec<String> {
389 .filter_map(|param| match is_a_ref_mut_param(¶m) {
390 // Maybe better filter the param name (to do this maybe extract a function from
391 // `arguments_from_params`?) in case of a `mut a: &mut T`. Anyway managing most (not
392 // all) cases might be enough, the goal is just to produce a template.
393 true => Some(param.pat()?.to_string()),
399 /// Helper function to build the comma-separated list of arguments of the function
400 fn arguments_from_params(param_list: &ast::ParamList) -> String {
401 let args_iter = param_list.params().map(|param| match param.pat() {
402 // To avoid `mut` in the function call (which would be a nonsense), `Pat` should not be
403 // written as is so its variants must be managed independently. Other variants (for
404 // instance `TuplePat`) could be managed later.
405 Some(ast::Pat::IdentPat(ident_pat)) => match ident_pat.name() {
406 Some(name) => match is_a_ref_mut_param(¶m) {
407 true => format!("&mut {}", name),
408 false => name.to_string(),
410 None => "_".to_string(),
412 _ => "_".to_string(),
414 args_iter.format(", ").to_string()
417 /// Helper function to build a function call. `None` if expected `self_name` was not provided
420 param_list: &ast::ParamList,
421 self_name: Option<&str>,
423 ) -> Option<String> {
424 let name = ast_func.name()?;
425 let arguments = arguments_from_params(param_list);
426 let function_call = if param_list.self_param().is_some() {
427 format!("{}.{}({})", self_name?, name, arguments)
428 } else if let Some(implementation) = self_partial_type(ast_func) {
429 format!("{}::{}({})", implementation, name, arguments)
431 format!("{}({})", name, arguments)
434 true => Some(format!("unsafe {{ {} }}", function_call)),
435 false => Some(function_call),
439 /// Helper function to count the parameters including `self`
440 fn count_parameters(param_list: &ast::ParamList) -> usize {
441 param_list.params().count() + if param_list.self_param().is_some() { 1 } else { 0 }
444 /// Helper function to transform lines of documentation into a Rust code documentation
445 fn documentation_from_lines(doc_lines: Vec<String>, indent_level: IndentLevel) -> String {
446 let mut result = String::new();
447 for doc_line in doc_lines {
448 result.push_str("///");
449 if !doc_line.is_empty() {
451 result.push_str(&doc_line);
454 result.push_str(&indent_level.to_string());
459 /// Helper function to transform an array of borrowed strings to an owned `Vec<String>`
460 fn string_vec_from(string_array: &[&str]) -> Vec<String> {
461 string_array.iter().map(|&s| s.to_owned()).collect()
464 /// Helper function to build the path of the module in the which is the node
465 fn build_path(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<String> {
466 let crate_name = crate_name(ast_func, ctx)?;
467 let leaf = self_partial_type(ast_func)
468 .or_else(|| ast_func.name().map(|n| n.to_string()))
469 .unwrap_or_else(|| "*".into());
470 let module_def: ModuleDef = ctx.sema.to_def(ast_func)?.module(ctx.db()).into();
471 match module_def.canonical_path(ctx.db()) {
472 Some(path) => Some(format!("{}::{}::{}", crate_name, path, leaf)),
473 None => Some(format!("{}::{}", crate_name, leaf)),
477 /// Helper function to get the return type of a function
478 fn return_type(ast_func: &ast::Fn) -> Option<ast::Type> {
479 ast_func.ret_type()?.ty()
482 /// Helper function to determine if the function returns some data
483 fn returns_a_value(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> bool {
486 .map(|hir_func| hir_func.ret_type(ctx.db()))
487 .map(|ret_ty| !ret_ty.is_unit() && !ret_ty.is_never())
493 use crate::tests::{check_assist, check_assist_not_applicable};
498 fn not_applicable_on_function_calls() {
499 check_assist_not_applicable(
500 generate_documentation_template,
503 fn calls_hello_world() {
511 fn not_applicable_in_trait_impl() {
512 check_assist_not_applicable(
513 generate_documentation_template,
517 impl MyTrait for MyStruct {
525 fn not_applicable_if_function_already_documented() {
526 check_assist_not_applicable(
527 generate_documentation_template,
529 /// Some documentation here
530 pub fn $0documented_function() {}
536 fn supports_noop_function() {
538 generate_documentation_template,
550 fn is_applicable_if_function_is_private() {
552 generate_documentation_template,
564 fn no_doc_example_for_private_fn() {
565 check_assist_not_applicable(
566 generate_doc_example,
575 fn supports_a_parameter() {
577 generate_doc_example,
580 pub fn noop_with_param(_a: i32) {}
588 /// use test::noop_with_param;
590 /// noop_with_param(_a);
592 pub fn noop_with_param(_a: i32) {}
598 fn detects_unsafe_function() {
600 generate_documentation_template,
602 pub unsafe fn no$0op_unsafe() {}
610 pub unsafe fn noop_unsafe() {}
614 generate_doc_example,
621 pub unsafe fn noop_unsafe() {}
633 /// use test::noop_unsafe;
635 /// unsafe { noop_unsafe() };
637 pub unsafe fn noop_unsafe() {}
643 fn guesses_panic_macro_can_panic() {
645 generate_documentation_template,
647 pub fn panic$0s_if(a: bool) {
659 pub fn panics_if(a: bool) {
669 fn guesses_assert_macro_can_panic() {
671 generate_documentation_template,
673 pub fn $0panics_if_not(a: bool) {
683 pub fn panics_if_not(a: bool) {
691 fn guesses_unwrap_can_panic() {
693 generate_documentation_template,
695 pub fn $0panics_if_none(a: Option<()>) {
705 pub fn panics_if_none(a: Option<()>) {
713 fn guesses_expect_can_panic() {
715 generate_documentation_template,
717 pub fn $0panics_if_none2(a: Option<()>) {
727 pub fn panics_if_none2(a: Option<()>) {
735 fn checks_output_in_example() {
737 generate_doc_example,
740 pub fn returns_a_value$0() -> i32 {
750 /// use test::returns_a_value;
752 /// assert_eq!(returns_a_value(), );
754 pub fn returns_a_value() -> i32 {
762 fn detects_result_output() {
764 generate_documentation_template,
766 pub fn returns_a_result$0() -> Result<i32, std::io::Error> {
775 /// This function will return an error if .
776 pub fn returns_a_result() -> Result<i32, std::io::Error> {
784 fn checks_ref_mut_in_example() {
786 generate_doc_example,
789 pub fn modifies_a_value$0(a: &mut i32) {
799 /// use test::modifies_a_value;
802 /// modifies_a_value(&mut a);
805 pub fn modifies_a_value(a: &mut i32) {
813 fn stores_result_if_at_least_3_params() {
815 generate_doc_example,
818 pub fn sum3$0(a: i32, b: i32, c: i32) -> i32 {
830 /// let result = sum3(a, b, c);
831 /// assert_eq!(result, );
833 pub fn sum3(a: i32, b: i32, c: i32) -> i32 {
841 fn supports_fn_in_mods() {
843 generate_doc_example,
860 /// use test::a::b::noop;
872 fn supports_fn_in_impl() {
874 generate_doc_example,
890 /// use test::MyStruct;
892 /// MyStruct::noop();
901 fn supports_unsafe_fn_in_trait() {
903 generate_documentation_template,
906 unsafe fn unsafe_funct$0ion_trait();
916 unsafe fn unsafe_function_trait();
923 fn supports_fn_in_trait_with_default_panicking() {
925 generate_documentation_template,
928 fn function_trait_with_$0default_panicking() {
940 fn function_trait_with_default_panicking() {
949 fn supports_fn_in_trait_returning_result() {
951 generate_documentation_template,
954 fn function_tr$0ait_returning_result() -> Result<(), std::io::Error>;
963 /// This function will return an error if .
964 fn function_trait_returning_result() -> Result<(), std::io::Error>;
973 generate_documentation_template,
975 pub struct String(u8);
977 pub fn new$0(x: u8) -> String {
983 pub struct String(u8);
985 /// Creates a new [`String`].
986 pub fn new(x: u8) -> String {
993 generate_documentation_template,
995 #[derive(Debug, PartialEq)]
996 pub struct MyGenericStruct<T> {
999 impl<T> MyGenericStruct<T> {
1000 pub fn new$0(x: T) -> MyGenericStruct<T> {
1001 MyGenericStruct { x }
1006 #[derive(Debug, PartialEq)]
1007 pub struct MyGenericStruct<T> {
1010 impl<T> MyGenericStruct<T> {
1011 /// Creates a new [`MyGenericStruct<T>`].
1012 pub fn new(x: T) -> MyGenericStruct<T> {
1013 MyGenericStruct { x }
1021 fn removes_one_lifetime_from_description() {
1023 generate_documentation_template,
1025 #[derive(Debug, PartialEq)]
1026 pub struct MyGenericStruct<'a, T> {
1029 impl<'a, T> MyGenericStruct<'a, T> {
1030 pub fn new$0(x: &'a T) -> Self {
1031 MyGenericStruct { x }
1036 #[derive(Debug, PartialEq)]
1037 pub struct MyGenericStruct<'a, T> {
1040 impl<'a, T> MyGenericStruct<'a, T> {
1041 /// Creates a new [`MyGenericStruct<T>`].
1042 pub fn new(x: &'a T) -> Self {
1043 MyGenericStruct { x }
1051 fn removes_all_lifetimes_from_description() {
1053 generate_documentation_template,
1055 #[derive(Debug, PartialEq)]
1056 pub struct MyGenericStruct<'a, 'b, T> {
1060 impl<'a, 'b, T> MyGenericStruct<'a, 'b, T> {
1061 pub fn new$0(x: &'a T, y: &'b T) -> Self {
1062 MyGenericStruct { x, y }
1067 #[derive(Debug, PartialEq)]
1068 pub struct MyGenericStruct<'a, 'b, T> {
1072 impl<'a, 'b, T> MyGenericStruct<'a, 'b, T> {
1073 /// Creates a new [`MyGenericStruct<T>`].
1074 pub fn new(x: &'a T, y: &'b T) -> Self {
1075 MyGenericStruct { x, y }
1083 fn removes_all_lifetimes_and_brackets_from_description() {
1085 generate_documentation_template,
1087 #[derive(Debug, PartialEq)]
1088 pub struct MyGenericStruct<'a, 'b> {
1092 impl<'a, 'b> MyGenericStruct<'a, 'b> {
1093 pub fn new$0(x: &'a usize, y: &'b usize) -> Self {
1094 MyGenericStruct { x, y }
1099 #[derive(Debug, PartialEq)]
1100 pub struct MyGenericStruct<'a, 'b> {
1104 impl<'a, 'b> MyGenericStruct<'a, 'b> {
1105 /// Creates a new [`MyGenericStruct`].
1106 pub fn new(x: &'a usize, y: &'b usize) -> Self {
1107 MyGenericStruct { x, y }
1115 fn detects_new_with_self() {
1117 generate_documentation_template,
1119 #[derive(Debug, PartialEq)]
1120 pub struct MyGenericStruct2<T> {
1123 impl<T> MyGenericStruct2<T> {
1124 pub fn new$0(x: T) -> Self {
1125 MyGenericStruct2 { x }
1130 #[derive(Debug, PartialEq)]
1131 pub struct MyGenericStruct2<T> {
1134 impl<T> MyGenericStruct2<T> {
1135 /// Creates a new [`MyGenericStruct2<T>`].
1136 pub fn new(x: T) -> Self {
1137 MyGenericStruct2 { x }
1145 fn supports_method_call() {
1147 generate_doc_example,
1149 impl<T> MyGenericStruct<T> {
1151 pub fn consume(self) {}
1155 impl<T> MyGenericStruct<T> {
1161 /// use test::MyGenericStruct;
1163 /// let my_generic_struct = ;
1164 /// my_generic_struct.consume();
1166 pub fn consume(self) {}
1173 fn checks_modified_self_param() {
1175 generate_doc_example,
1177 impl<T> MyGenericStruct<T> {
1179 pub fn modify(&mut self, new_value: T) {
1185 impl<T> MyGenericStruct<T> {
1191 /// use test::MyGenericStruct;
1193 /// let mut my_generic_struct = ;
1194 /// my_generic_struct.modify(new_value);
1195 /// assert_eq!(my_generic_struct, );
1197 pub fn modify(&mut self, new_value: T) {
1206 fn generates_intro_for_getters() {
1208 generate_documentation_template,
1212 pub fn speed$0(&self) -> f32 { 0.0 }
1218 /// Returns the speed of this [`S`].
1219 pub fn speed(&self) -> f32 { 0.0 }
1224 generate_documentation_template,
1228 pub fn data$0(&self) -> &[u8] { &[] }
1234 /// Returns a reference to the data of this [`S`].
1235 pub fn data(&self) -> &[u8] { &[] }
1240 generate_documentation_template,
1244 pub fn data$0(&mut self) -> &mut [u8] { &mut [] }
1250 /// Returns a mutable reference to the data of this [`S`].
1251 pub fn data(&mut self) -> &mut [u8] { &mut [] }
1256 generate_documentation_template,
1260 pub fn data_mut$0(&mut self) -> &mut [u8] { &mut [] }
1266 /// Returns a mutable reference to the data of this [`S`].
1267 pub fn data_mut(&mut self) -> &mut [u8] { &mut [] }
1274 fn no_getter_intro_for_prefixed_methods() {
1276 generate_documentation_template,
1280 pub fn as_bytes$0(&self) -> &[u8] { &[] }
1287 pub fn as_bytes(&self) -> &[u8] { &[] }
1294 fn generates_intro_for_setters() {
1296 generate_documentation_template,
1300 pub fn set_data$0(&mut self, data: Vec<u8>) {}
1306 /// Sets the data of this [`S`].
1307 pub fn set_data(&mut self, data: Vec<u8>) {}
1312 generate_documentation_template,
1316 pub fn set_domain_name$0(&mut self, name: String) {}
1322 /// Sets the domain name of this [`S`].
1323 pub fn set_domain_name(&mut self, name: String) {}