Skip to content

Resource propertiesย #235

Open
Open
@badeend

Description

@badeend

Most languages have either:

  • language-level support for properties
    • C#: string MyProperty { get; set; }
    • JavaScript: get myProperty()
    • JavaScript: set myProperty(value)
  • or conventions on how to name property-like methods.
    • Java: String getMyProperty()
    • Java: void setMyProperty(String value)
    • Rust: my_property(&self) -> String
    • Rust: set_my_property(&mut self, value: String) -> ()

If properties are not encoded natively in WIT, we'll probably end up with everybody choosing their own convention (based on their own language). Which is bound to end up looking foreign to the other languages.
Or we can prescribe a convention for tooling to convert from&to, but at that point we might as well just encode it into Wit itself.

My suggestion:

interface abc {
    resource blob {
        content-type1: string { get } // Read-only property
        content-type2: string { set } // Write-only property
        content-type3: string { get, set } // Read/write property

        content-type4: string // TODO: Without annotation defaults to { get } ? Or { get, set } ?

        content-type5: string { // Customized signatures
            get -> result<string, my-get-error>,
            set -> result<_, my-set-error>,
        }
        content-type6: string { // Infallible getter, fallible setter
            get, // If no custom signature is provided, the getter/setter is assumed to be infallible.
            set -> result<_, my-set-error>,
        }

        /// General doc-comment applicable to both the getter & setter.
        content-type7: string {
            /// Documentation specific to the getter.
            get,

            /// Documentation specific to the setter.
            set,
        }
    }

    // Is equivalent to:



    resource blob
    %[get]blob.content-type1: func(self: borrow<blob>) -> string
    %[set]blob.content-type2: func(self: borrow<blob>, value: string)
    %[get]blob.content-type3: func(self: borrow<blob>) -> string
    %[set]blob.content-type3: func(self: borrow<blob>, value: string)

    // %[???]blob.content-type4

    %[get]blob.content-type5: func(self: borrow<blob>) -> result<string, my-get-error>
    %[set]blob.content-type5: func(self: borrow<blob>, value: string) -> result<_, my-set-error>
    %[get]blob.content-type6: func(self: borrow<blob>) -> string
    %[set]blob.content-type6: func(self: borrow<blob>, value: string) -> result<_, my-set-error>

}

Or more Javascript-esque:

interface abc {
    resource blob {
        // Together these two declarations represent one logical property.
        content-type: get func() -> string
        content-type: set func(value: string)
    }
}

Either way, in both variants getters and setters:

  • are never async
  • always borrow their self argument, regardless of the outcome of Allow consuming methodsย #226
  • must satisfy one of these signatures:
    • %[get]T.property-name: func(self: borrow<T>) -> T
    • %[get]T.property-name: func(self: borrow<T>) -> result<T, error-type>
    • %[set]T.property-name: func(self: borrow<T>, value: T)
    • %[set]T.property-name: func(self: borrow<T>, value: T) -> result<_, error-type>

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions