|  | # Bind Library Guidelines | 
|  |  | 
|  | ## Fuchsia namespace and scope | 
|  |  | 
|  | All bind libraries defined in the Fuchsia tree (`fuchsia.git`) must follow these | 
|  | rules for the namespace: | 
|  |  | 
|  | *   If the bind library is used for internal testing and excluded from the SDK, | 
|  | the top-level namespace must be test | 
|  | *   Otherwise, the top-level namespace must be `fuchsia`. This signals that the | 
|  | bind libraries are part of the open-source Fuchsia project. | 
|  |  | 
|  | ## Bind library scope | 
|  |  | 
|  | Bind libraries should scoped by one of the following: | 
|  |  | 
|  | *   Vendor platform | 
|  | *   Hardware functionality | 
|  | *   Deprecated Banjo protocol | 
|  |  | 
|  | ### Vendor platform | 
|  |  | 
|  | Bind libraries scoped by a vendor platform define properties that are associated | 
|  | with hardware from the vendor. For example, a vendor such as Amlogic has their | 
|  | own database of product IDs (PID) that they maintain. | 
|  |  | 
|  | At a high level, the bind library’s namespace should follow the format: | 
|  |  | 
|  | ``` | 
|  | fuchsia.<vendor>.platform | 
|  | ``` | 
|  |  | 
|  | Bind libraries can be scoped down further by specific hardware or functionality | 
|  | through namespace nesting. For instance, a high level bind library for Amlogic | 
|  | hardware would have the namespace `fuchsia.amlogic.platform`. | 
|  |  | 
|  | If we want a bind library for the Amlogic Meson lineup, we can define it in the | 
|  | `fuchsia.amlogic.platform.meson` namespace. If we want a bind library for | 
|  | Amlogic hardware with display functionality, we can define it in the namespace | 
|  | `fuchsia.amlogic.platform.display`. | 
|  |  | 
|  | ### Hardware functionality | 
|  |  | 
|  | Bind libraries that’s scoped by hardware functionality contain properties | 
|  | related to the functionality. The namespace should follow the format: | 
|  |  | 
|  | ``` | 
|  | fuchsia.<hardware function> | 
|  | ``` | 
|  |  | 
|  | These bind libraries are considered to be high level and generic. As such the | 
|  | properties can be extended by any vendor platform bind libraries. | 
|  |  | 
|  | The hardware functionality namespace can be divided to more specific bind | 
|  | libraries through nesting. For example, the `fuchsia.usb` bind library contains | 
|  | high level properties for USB devices. If we want to define properties specific | 
|  | to USB mass storage devices, we can define them in a `fuchsia.usb.massstorage` | 
|  | bind library. | 
|  |  | 
|  | ### Deprecated Banjo protocol | 
|  |  | 
|  | Bind libraries scoped by Banjo protocols contain properties that represent the | 
|  | devices implementing the protocol. These libraries are established due to legacy | 
|  | code and should be phased out into hardware functionality scoped libraries. | 
|  |  | 
|  | ## Naming | 
|  |  | 
|  | ### Namespace components | 
|  |  | 
|  | Each component of the name is in lowercase and must match the regular expression | 
|  | `[a-z][a-z0-9]*`. | 
|  |  | 
|  | ### Property keys and values | 
|  |  | 
|  | Prefer screaming snake case for the property keys and values. This improves the | 
|  | readability for the generated constants in the language bindings. | 
|  |  | 
|  | For example, given the following bind library | 
|  |  | 
|  | ``` | 
|  | library fuchsia.input; | 
|  |  | 
|  | enum DEVICE_CATEGORY { | 
|  | KEYBOARD, | 
|  | MOUSE, | 
|  | }; | 
|  | ``` | 
|  |  | 
|  | The following constants are generated: | 
|  |  | 
|  | * {C++} | 
|  |  | 
|  | ``` | 
|  | // WARNING: This file is machine generated by bindc. | 
|  |  | 
|  | #ifndef BIND_FUCHSIA_INPUT_BINDLIB_ | 
|  | #define BIND_FUCHSIA_INPUT_BINDLIB_ | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | namespace bind_fuchsia_input { | 
|  |  | 
|  | static const std::string DEVICE_CATEGORY = "fuchsia.input.DEVICE_CATEGORY"; | 
|  | static const std::string DEVICE_CATEGORY_KEYBOARD = "fuchsia.input.DEVICE_CATEGORY.KEYBOARD"; | 
|  | static const std::string DEVICE_CATEGORY_MOUSE = "fuchsia.input.DEVICE_CATEGORY.MOUSE"; | 
|  |  | 
|  | }  // namespace bind_fuchsia_input | 
|  |  | 
|  | #endif  // BIND_FUCHSIA_INPUT_BINDLIB_ | 
|  | ``` | 
|  |  | 
|  | * {Rust} | 
|  |  | 
|  | ``` | 
|  | // WARNING: This file is machine generated by bindc. | 
|  |  | 
|  | pub const DEVICE_CATEGORY: &str = "fuchsia.example.library.DeviceCategory"; | 
|  | pub const DEVICE_CATEGORY_KEYBOARD: &str = | 
|  | "fuchsia.input.DEVICE_CATEGORY.KEYBOARD"; | 
|  | pub const DEVICE_CATEGORY_MOUSE: &str = | 
|  | "fuchsia.input.DEVICE_CATEGORY.MOUSE"; | 
|  | ``` | 
|  |  | 
|  | ## Types | 
|  |  | 
|  | ### Prefer enum types over string for bound sets | 
|  |  | 
|  | Enum types are preferred for properties with a limited set of values that are | 
|  | statically known. For example, `fuchsia.hardware.gpio.FUNCTION` property is more | 
|  | suitable as an enum type because the set of functionality is known statically | 
|  | for each board. | 
|  |  | 
|  | In a scenario where it’s possible that new values need to be added to the | 
|  | property, using enum may still be preferable. The property values can scale by | 
|  | extending the property from a new bind library. | 
|  |  | 
|  | If the property values are flexible with a wide range, then string types are | 
|  | preferred. One example is the ACPI HID value, which is a character string that | 
|  | identifies the manufacturer of the device and the specific device manufactured | 
|  | by the vendor (ex/ "PRP0001"). | 
|  |  | 
|  | ### Use integer values for external registries | 
|  |  | 
|  | Integer values are more appropriate for properties that represent number-based | 
|  | values maintained externally by a well known registry, such as the vendor IDs in | 
|  | the PCI ID registry and the class codes in the USB registry. | 
|  |  | 
|  | ### Avoid adding new properties to the legacy bind library | 
|  |  | 
|  | Legacy properties are defined in the | 
|  | [`fuchsia` bind library](/src/devices/bind/fuchsia/fuchsia.bind) and | 
|  | [`binding_priv.h`](/src/lib/ddk/include/lib/ddk/binding_priv.h). Since these | 
|  | properties are deprecated and are in the process of being phased out, avoid | 
|  | adding any new properties to them as much as possible. | 
|  |  | 
|  | ## Extending properties | 
|  |  | 
|  | Bind libraries should only extend properties from other bind libraries that are | 
|  | higher up in its namespace or from libraries that are scoped by hardware | 
|  | functionality. | 
|  |  | 
|  | If the bind library is scoped by hardware functionality, then it should only | 
|  | extend from the bind libraries higher up in its namespace. For example, the | 
|  | `fuchsia.usb.audio` bind library can only extend properties from the | 
|  | `fuchsia.usb` and `fuchsia` bind library. | 
|  |  | 
|  | Vendor platform bind libraries can extend from any hardware functionality bind | 
|  | libraries. | 
|  |  | 
|  | ### Extending from legacy properties | 
|  |  | 
|  | The legacy fuchsia bind library is at the highest level. All bind libraries can | 
|  | extend from it. However, since these properties are deprecated, we should avoid | 
|  | extending the properties and favor introducing new properties instead. |