Azure / Azure/typespec-rust

Compilation error: the trait bound Clone is not satisfied (for generated types) + same for `serde::Serialize` trait

Open
#917 9 comments 0 reactions 0 assignees View on GitHub
CodeGen
Dominant language
Rust
Stars
7
Forks
11
Avg merge
2d 5h
Merged PRs (30d)
5

Description

This affects
* `specification/quantum/Quantum.Workspace`
* `specification/eventgrid/data-plane/EventGridNamespace`
* `specification/communication/Communication.Messages`
* `specification/devcenter/DevCenter`
* `specification/computeschedule/ComputeSchedule.Management`
* `specification/cognitiveservices/OpenAI.Inference`
* `specification/healthdataaiservices/HealthDataAIServices.DeidServices`

I think this happens when a type is also used as an OperationStatus.

I.e.
```rs
...
/// A job to be run in the workspace.
#[derive(Default, Deserialize, SafeDebug)]
#[serde(rename = "Job", tag = "itemType")]
pub struct JobDetails {
/// The time when the item began execution.
///
/// Operational visibility: Read
#[serde(
default,
rename = "beginExecutionTime",
skip_serializing_if = "Option::is_none",
with = "azure_core::time::rfc3339::option"
)]
pub begin_execution_time: Option,

/// The time when a job was successfully cancelled.
///
/// Operational visibility: Read
#[serde(
default,
rename = "cancellationTime",
skip_serializing_if = "Option::is_none",
with = "azure_core::time::rfc3339::option"
)]
pub cancellation_time: Option,

/// The blob container SAS uri, the container is used to host job data.
///
/// Operational visibility: Create, Read
#[serde(rename = "containerUri", skip_serializing_if = "Option::is_none")]
pub container_uri: Option,

/// Cost estimate.
///
/// Operational visibility: Read
#[serde(rename = "costEstimate", skip_serializing_if = "Option::is_none")]
pub cost_estimate: Option,

/// The identity that created the item.
///
/// Operational visibility: Read
#[serde(rename = "createdBy", skip_serializing_if = "Option::is_none")]
pub created_by: Option,

/// The type of identity that created the item.
///
/// Operational visibility: Read
#[serde(rename = "createdByType", skip_serializing_if = "Option::is_none")]
pub created_by_type: Option,

/// The creation time of the item.
///
/// Operational visibility: Read
#[serde(
default,
rename = "creationTime",
skip_serializing_if = "Option::is_none",
with = "azure_core::time::rfc3339::option"
)]
pub creation_time: Option,

/// The time when the item finished execution.
///
/// Operational visibility: Read
#[serde(
default,
rename = "endExecutionTime",
skip_serializing_if = "Option::is_none",
with = "azure_core::time::rfc3339::option"
)]
pub end_execution_time: Option,

/// Error information.
///
/// Operational visibility: Read
#[serde(rename = "errorData", skip_serializing_if = "Option::is_none")]
pub error_data: Option,

/// Id of the job.
///
/// Operational visibility: Read
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option,

/// The format of the input data.
///
/// Operational visibility: Create, Read
#[serde(rename = "inputDataFormat", skip_serializing_if = "Option::is_none")]
pub input_data_format: Option,

/// The input blob URI, if specified, it will override the default input blob in the container.
///
/// Operational visibility: Create, Read
#[serde(rename = "inputDataUri", skip_serializing_if = "Option::is_none")]
pub input_data_uri: Option,

/// The input parameters for the job. JSON object used by the target solver. It is expected that the size of this object is
/// small and only used to specify parameters for the execution target, not the input data.
///
/// Operational visibility: Create, Read
#[serde(rename = "inputParams", skip_serializing_if = "Option::is_none")]
pub input_params: Option,

/// The type of job.
///
/// Operational visibility: Create, Read
#[serde(rename = "jobType", skip_serializing_if = "Option::is_none")]
pub job_type: Option,

/// The identity that last modified the item.
///
/// Operational visibility: Read
#[serde(rename = "lastModifiedBy", skip_serializing_if = "Option::is_none")]
pub last_modified_by: Option,

/// The type of identity that last modified the item.
///
/// Operational visibility: Read
#[serde(rename = "lastModifiedByType", skip_serializing_if = "Option::is_none")]
pub last_modified_by_type: Option,

/// The timestamp of the item last modification initiated by the customer.
///
/// Operational visibility: Read
#[serde(
default,
rename = "lastModifiedTime",
skip_serializing_if = "Option::is_none",
with = "azure_core::time::rfc3339::option"
)]
pub last_modified_time: Option,

/// The last time the item was updated by the system.
///
/// Operational visibility: Read
#[serde(
default,
rename = "lastUpdatedTime",
skip_serializing_if = "Option::is_none",
with = "azure_core::time::rfc3339::option"
)]
pub last_updated_time: Option,

/// The job metadata. Metadata provides client the ability to store client-specific information
///
/// Operational visibility: Create, Read, Update
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option,

/// The name of the item. It is not required for the name to be unique and it's only used for display purposes.
///
/// Operational visibility: Create, Read, Update
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option,

/// The format of the output data.
///
/// Operational visibility: Create, Read
#[serde(rename = "outputDataFormat", skip_serializing_if = "Option::is_none")]
pub output_data_format: Option,

/// The output blob uri. When a job finishes successfully, results will be uploaded to this blob.
///
/// Operational visibility: Create, Read
#[serde(rename = "outputDataUri", skip_serializing_if = "Option::is_none")]
pub output_data_uri: Option,

/// Priority of job or session.
///
/// Operational visibility: Create, Read, Update
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option,

/// The unique identifier for the provider.
///
/// Operational visibility: Create, Read
#[serde(rename = "providerId", skip_serializing_if = "Option::is_none")]
pub provider_id: Option,

/// Quantum computing data.
///
/// Operational visibility: Read
#[serde(
rename = "quantumComputingData",
skip_serializing_if = "Option::is_none"
)]
pub quantum_computing_data: Option,

/// The ID of the session that the job is part of.
///
/// Operational visibility: Create, Read
#[serde(rename = "sessionId", skip_serializing_if = "Option::is_none")]
pub session_id: Option,

/// The status of the job.
///
/// Operational visibility: Read
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option,

/// List of user-supplied tags associated with the job.
///
/// Operational visibility: Create, Read, Update
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option>,

/// The target identifier to run the job.
///
/// Operational visibility: Create, Read
#[serde(skip_serializing_if = "Option::is_none")]
pub target: Option,

/// Resource consumption metrics containing provider-specific usage data such as execution time, quantum shots consumed etc.
///
/// Operational visibility: Read
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option,
}
...
```

and then it is used elsewhere, i.e. here it is used in Pageable

```rs
/// Paged collection of JobDetails items
#[derive(Clone, Default, Deserialize, SafeDebug, Serialize)]
#[non_exhaustive]
pub struct PagedJobDetails {
/// The link to the next page of items
#[serde(rename = "nextLink", skip_serializing_if = "Option::is_none")]
pub next_link: Option,

/// The JobDetails items on this page
#[serde(default)]
pub value: Vec,
}
```

But it's not only when Pageable, i.e.
```rs
/// The error object.
#[derive(Default, Deserialize, SafeDebug)]
#[non_exhaustive]
pub struct WorkspaceItemError {
/// One of a server-defined set of error codes.
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option,

/// An array of details about specific errors that led to this reported error.
#[serde(skip_serializing_if = "Option::is_none")]
pub details: Option>,

/// An object containing more specific information than the current object about the error.
#[serde(skip_serializing_if = "Option::is_none")]
pub innererror: Option,

/// A human-readable representation of the error.
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option,

/// The target of the error.
#[serde(skip_serializing_if = "Option::is_none")]
pub target: Option,
}

...

/// A workspace item.
#[derive(Serialize)]
pub(crate) struct UnknownItemDetailsItemType<'a> {
...

/// Error information.
///
/// Operational visibility: Read
#[serde(rename = "errorData")]
pub error_data: &'a Option,

...
}
```

I think the thing that is common is that the pub struct that doesn't have `Clone` is being used as LRO operation status. Maybe the fix is simple - to update a place in the code to include `Clone` there - there is a specific line responsible for that, maybe at a time we didn't add it simply because we thought it is not needed and kept things to a minimum.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.