Skip to content

Latest commit

 

History

History
109 lines (75 loc) · 3.91 KB

20241010-stringer-interface.md

File metadata and controls

109 lines (75 loc) · 3.91 KB
status flip authors sponsor updated
approved
293
Raymond Zhang ([email protected])
Supun Setunga ([email protected])
2024-10-30

FLIP 293: StructStringer Interface

Objective

This FLIP proposes the addition of a struct interface StructStringer to Cadence, which all string-convertible structs will implement. Note that some languages distinguish between a "human-readable representation" and a "debug representation". The purpose of the StructStringer interface is to help with providing "human-readable representations" of AnyStruct and is separate from the "debug representation" which already exists.

One goal of this FLIP is to simplify the process for representing AnyStruct as a String. Secondly, a customizable toString will be useful for future string formatting such as string interpolation with this interface.

Motivation

Currently if a developer wants to accept a value as AnyStruct and convert it to a string they have to identify which subtype the value belongs to and call the associated toString function. This leads to code such as the following

access(all) fun toString(_ value: AnyStruct): String? {
    if let stringValue = value as? String {
        return stringValue
    } else if let boolValue = value as? Bool {
        return boolValue ? "true" : "false"
    } else if let characterValue = value as? Character {
        return characterValue.toString()
    } else if let addressValue = value as? Address {
        return addressValue.toString()
    } else if let pathValue = value as? Path {
        return pathValue.toString()
    } else if let intValue = value as? Int {
        return intValue.toString()
    }
    ...
}

With the proposed addition, the code could be simplified to

access(all) fun toString(_ value: AnyStruct): String? {
    if let stringerValue = value as? {StructStringer} {
        return stringerValue.toString()
    }
}

Additionally a conforming struct can be converted to a String in the same function which was not previously possible. This can be useful for various string formatting functions.

User Benefit

This will significantly streamline the process of converting AnyStruct values to String which is useful for developers, in providing human readable descriptions. It also allows for more powerful string formatting functions.

Design Proposal

The proposed interface is as follows

access(all)
struct interface StructStringer {
    access(all)
    view fun toString(): String
}

The prefix Struct is present to make it clear this is a struct interface and in the future a resource interface can be added.

Drawbacks

As with all user-defined types there are risks associated with calling someone else's toString function such as panic or gas usage concerns that developers need to be aware of.

Alternatives Considered

An alternative is to have AnyStruct itself implement a toString function. As a native function there is no longer any risk of malicious code and it still solves the first goal. Additionally, it still allows for more powerful string formatting. The downside of this approach is in limiting customizability for developers.

Performance Implications

None.

Dependencies

None.

Engineering Impact

This change should be simple to implement.

Best Practices

Reduce code size in converting AnyStruct to String.

Compatibility

Proposed changes are backwards compatible.

User Impact

Feature addition, no impact.

Related Issues

string formatting

Prior Art

Many languages have an interface for formatting types as String such as