Skip to content

Improve #[var] + #[export] docs #1188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions godot-codegen/src/special_cases/special_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,8 @@ pub fn maybe_rename_virtual_method<'m>(
// TODO method-level extra docs, for:
// - Node::rpc_config() -> link to RpcConfig.
// - Node::process/physics_process -> mention `f32`/`f64` duality.
// - Node::duplicate -> to copy #[var] fields, needs STORAGE property usage, or #[export],
// or #[export(storage)] which is #[export] without editor UI.

pub fn get_class_extra_docs(class_name: &TyName) -> Option<&'static str> {
match class_name.godot_ty.as_str() {
Expand Down
1 change: 1 addition & 0 deletions godot-macros/src/class/data_models/field_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ impl ExportType {
}
}

/// Returns a `PropertyUsageFlags` identifier if this export type has a _usage_.
pub fn to_export_usage(&self) -> Option<Ident> {
match self {
Self::Storage => Some(ident("STORAGE")),
Expand Down
57 changes: 33 additions & 24 deletions godot-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ use crate::util::{bail, ident, KvParser};
/// (fields annotated with `@export`). In the gdext API, these two concepts are represented with `#[var]` and `#[export]` attributes respectively,
/// which in turn are backed by the [`Var`](../register/property/trait.Var.html) and [`Export`](../register/property/trait.Export.html) traits.
///
/// ## Property registration
/// ## Register properties -- `#[var]`
///
/// To create a property, you can use the `#[var]` annotation:
/// To create a property, you can use the `#[var]` annotation, which supports types implementing [`Var`](../register/property/trait.Var.html).
///
/// ```
/// # use godot::prelude::*;
Expand Down Expand Up @@ -207,9 +207,10 @@ use crate::util::{bail, ident, KvParser};
/// }
/// ```
///
/// ## Property exports
/// ## Export properties -- `#[export]`
///
/// For exporting properties to the editor, you can use the `#[export]` attribute:
/// To export properties to the editor, you can use the `#[export]` attribute, which supports types implementing
/// [`Export`](../register/property/trait.Export.html):
///
/// ```
/// # use godot::prelude::*;
Expand All @@ -221,19 +222,21 @@ use crate::util::{bail, ident, KvParser};
/// }
/// ```
///
/// If you don't also include a `#[var]` attribute, then a default one will be generated.
/// `#[export]` also supports all of GDScript's annotations, in a slightly different format. The format is
/// If you don't include an additional `#[var]` attribute, then a default one will be generated.
///
/// `#[export]` also supports all of [GDScript's annotations][gdscript-annotations], in a slightly different format. The format is
/// translated from an annotation by following these four rules:
///
/// - `@export` becomes `#[export]`
/// - `@export_{name}` becomes `#[export(name)]`
/// - `@export_{name}(elem1, ...)` becomes `#[export(name = (elem1, ...))]`
/// - `@export_{flags/enum}("elem1", "elem2:key2", ...)`
/// becomes
/// `#[export(flags/enum = (elem1, elem2 = key2, ...))]`
/// [gdscript-annotations]: https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html
///
/// | GDScript annotation | Rust attribute |
/// |---------------------------------------------|-------------------------------------------------|
/// | `@export` | `#[export]` |
/// | `@export_key` | `#[export(key)]` |
/// | `@export_key(elem1, ...)` | `#[export(key = (elem1, ...))]` |
/// | `@export_flags("elem1", "elem2:val2", ...)`<br>`@export_enum("elem1", "elem2:val2", ...)` | `#[export(flags = (elem1, elem2 = val2, ...))]`<br>`#[export(enum = (elem1, elem2 = val2, ...))]` |
///
/// As an example of some different export attributes:
/// As an example of different export attributes:
///
/// ```
/// # use godot::prelude::*;
Expand Down Expand Up @@ -279,9 +282,8 @@ use crate::util::{bail, ident, KvParser};
///
/// ```
///
/// Most values in expressions like `key = value`, can be an arbitrary expression that evaluates to the
/// right value. Meaning you can use constants or variables, as well as any other rust syntax you'd like in
/// the export attributes.
/// Most values in syntax such as `key = value` can be arbitrary expressions. For example, you can use constants, function calls or
/// other Rust expressions that are valid in that context.
///
/// ```
/// # use godot::prelude::*;
Expand All @@ -298,18 +300,24 @@ use crate::util::{bail, ident, KvParser};
/// }
/// ```
///
/// You can specify custom property hints, hint strings, and usage flags in a `#[var]` attribute using the
/// `hint`, `hint_string`, and `usage_flags` keys in the attribute. These are constants in the `PropertyHint`
/// and `PropertyUsageFlags` enums, respectively.
/// ## Low-level property hints and usage
///
/// ```
/// You can specify custom property hints, hint strings, and usage flags in a `#[var]` attribute using the `hint`, `hint_string`
/// and `usage_flags` keys in the attribute. Hint and usage flags are constants in the [`PropertyHint`] and [`PropertyUsageFlags`] enums,
/// while hint strings are dependent on the hint, property type and context. Using these low-level keys is rarely necessary, as most common
/// combinations are covered by `#[var]` and `#[export]` already.
///
/// [`PropertyHint`]: ../global/struct.PropertyHint.html
/// [`PropertyUsageFlags`]: ../global/struct.PropertyUsageFlags.html
///
/// ```no_run
/// # use godot::prelude::*;
/// #[derive(GodotClass)]
/// # #[class(init)]
/// struct MyStruct {
/// // Treated as an enum with two values: "One" and "Two"
/// // Displayed in the editor
/// // Treated as read-only by the editor
/// // Treated as an enum with two values: "One" and "Two",
/// // displayed in the editor,
/// // treated as read-only by the editor.
/// #[var(
/// hint = ENUM,
/// hint_string = "One,Two",
Expand All @@ -319,9 +327,10 @@ use crate::util::{bail, ident, KvParser};
/// }
/// ```
///
///
/// # Further class customization
///
/// ## Running code in the editor
/// ## Running code in the editor (tool)
///
/// If you annotate a class with `#[class(tool)]`, its lifecycle methods (`ready()`, `process()` etc.) will be invoked in the editor. This
/// is useful for writing custom editor plugins, as opposed to classes running simply in-game.
Expand Down
Loading