#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Service {
#[serde(default, skip_serializing_if = "Option::is_none",
serialize_with = "serialize_opt_string_or_struct",
deserialize_with = "deserialize_opt_string_or_struct")]
pub build: Option<Build>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub cap_add: Vec<RawOr<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub cap_drop: Vec<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<CommandLine>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cgroup_parent: Option<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub container_name: Option<RawOr<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub devices: Vec<RawOr<AliasedName>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub depends_on: Vec<RawOr<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty",
serialize_with = "serialize_item_or_list",
deserialize_with = "deserialize_string_or_list")]
pub dns: Vec<RawOr<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty",
serialize_with = "serialize_item_or_list",
deserialize_with = "deserialize_string_or_list")]
pub dns_search: Vec<RawOr<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty",
serialize_with = "serialize_item_or_list",
deserialize_with = "deserialize_string_or_list")]
pub tmpfs: Vec<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub entrypoint: Option<CommandLine>,
#[serde(rename = "env_file",
default, skip_serializing_if = "Vec::is_empty",
serialize_with = "serialize_item_or_list",
deserialize_with = "deserialize_string_or_list")]
pub env_files: Vec<RawOr<String>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty",
deserialize_with = "deserialize_map_or_key_value_list")]
pub environment: BTreeMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub expose: Vec<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub extends: Option<Extends>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub external_links: Vec<RawOr<AliasedName>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub extra_hosts: Vec<RawOr<HostMapping>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub image: Option<RawOr<String>>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty",
deserialize_with = "deserialize_map_or_key_value_list")]
pub labels: BTreeMap<String, String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub links: Vec<RawOr<AliasedName>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub logging: Option<Logging>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub network_mode: Option<RawOr<NetworkMode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub pid: Option<RawOr<PidMode>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub ports: Vec<RawOr<PortMapping>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub security_opt: Vec<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_signal: Option<RawOr<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volumes: Vec<RawOr<VolumeMount>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volumes_from: Vec<RawOr<VolumesFrom>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub volume_driver: Option<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu_shares: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cpu_quota: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub domainname: Option<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hostname: Option<RawOr<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ipc: Option<RawOr<IpcMode>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mac_address: Option<RawOr<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mem_limit: Option<RawOr<MemorySize>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memswap_limit: Option<RawOr<MemorySize>>,
#[serde(default, skip_serializing_if = "is_false")]
pub privileged: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub restart: Option<RawOr<RestartMode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub shm_size: Option<RawOr<MemorySize>>,
#[serde(default, skip_serializing_if = "is_false")]
pub stdin_open: bool,
#[serde(default, skip_serializing_if = "is_false")]
pub tty: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<RawOr<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub working_dir: Option<RawOr<PathBuf>>,
}
#[test]
fn service_handles_sample_fields_correctly() {
let yaml = r#"---
"dns": "8.8.8.8"
"dns_search":
- "example.com"
- "example.net"
"image": "hello"
"#;
assert_roundtrip!(Service, yaml);
}
#[test]
fn service_env_file_is_renamed() {
let yaml = r#"---
"env_file":
- "foo/bar.env"
"#;
let service: Service = serde_yaml::from_str(&yaml).unwrap();
assert_eq!(service.env_files.len(), 1);
assert_eq!(service.env_files[0], escape("foo/bar.env").unwrap());
}