summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuebinm2022-11-05 02:51:09 +0100
committerstuebinm2022-11-05 02:51:09 +0100
commitf3daba4974b1e543e14e7a626bf2d0bcdcd4190f (patch)
treebfc3e330dc67c65d665ecf8254c5e52643c10e9d
intial commit: simple printing of feeds
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock1190
-rw-r--r--Cargo.toml16
-rw-r--r--build.rs15
-rw-r--r--src/main.rs28
-rw-r--r--src/protos.rs4
-rw-r--r--src/protos/gtfs-realtime.proto1024
7 files changed, 2278 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..bd62e27
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,1190 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
+[[package]]
+name = "bytes"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
+
+[[package]]
+name = "cc"
+version = "1.0.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "4.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e67816e006b17427c9b4386915109b494fec2d929c63e3bd3561234cbf1bf1e"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_derive",
+ "clap_lex",
+ "once_cell",
+ "strsim",
+ "termcolor",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
+name = "either"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "fastrand"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
+
+[[package]]
+name = "futures-task"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
+
+[[package]]
+name = "futures-util"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "http"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
+dependencies = [
+ "http",
+ "hyper",
+ "rustls",
+ "tokio",
+ "tokio-rustls",
+]
+
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
+
+[[package]]
+name = "itoa"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+
+[[package]]
+name = "lock_api"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
+name = "mio"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+
+[[package]]
+name = "os_str_bytes"
+version = "6.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "protobuf"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e"
+dependencies = [
+ "once_cell",
+ "protobuf-support",
+ "thiserror",
+]
+
+[[package]]
+name = "protobuf-codegen"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901"
+dependencies = [
+ "anyhow",
+ "once_cell",
+ "protobuf",
+ "protobuf-parse",
+ "regex",
+ "tempfile",
+ "thiserror",
+]
+
+[[package]]
+name = "protobuf-parse"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "log",
+ "protobuf",
+ "protobuf-support",
+ "tempfile",
+ "thiserror",
+ "which",
+]
+
+[[package]]
+name = "protobuf-support"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372"
+dependencies = [
+ "thiserror",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+
+[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.11.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc"
+dependencies = [
+ "base64",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-rustls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "webpki-roots",
+ "winreg",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "rustls"
+version = "0.20.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
+dependencies = [
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55"
+dependencies = [
+ "base64",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "sct"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.147"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
+
+[[package]]
+name = "serde_json"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "showrt"
+version = "0.1.0"
+dependencies = [
+ "clap",
+ "protobuf",
+ "protobuf-codegen",
+ "reqwest",
+ "tokio",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+
+[[package]]
+name = "socket2"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "libc",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "tokio"
+version = "1.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
+dependencies = [
+ "autocfg",
+ "bytes",
+ "libc",
+ "memchr",
+ "mio",
+ "num_cpus",
+ "parking_lot",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "winapi",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.23.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+dependencies = [
+ "rustls",
+ "tokio",
+ "webpki",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "url"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "want"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "web-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.22.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
+name = "which"
+version = "4.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
+dependencies = [
+ "either",
+ "libc",
+ "once_cell",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
+[[package]]
+name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..8417c6b
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "showrt"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[build-dependencies]
+protobuf-codegen = "3.2"
+
+[dependencies]
+protobuf = "3.2.0"
+
+reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features = false }
+tokio = { version = "1", features = ["full"] }
+clap = { version = "4", features = ["derive"] }
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..fa4ca4a
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,15 @@
+
+
+fn main () {
+protobuf_codegen::Codegen::new()
+ // Use `protoc` parser, optional.
+ .protoc()
+ // All inputs and imports from the inputs must reside in `includes` directories.
+ .include("src/protos")
+ // Inputs must reside in some of include paths.
+ .input("src/protos/gtfs-realtime.proto")
+ // Specify output directory relative to Cargo output directory.
+ .cargo_out_dir("protos")
+ .run_from_script();
+
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..fd02f82
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,28 @@
+
+mod protos;
+use protos::protos::gtfs_realtime::FeedMessage;
+
+use protobuf::Message;
+use clap::Parser;
+
+#[derive(Parser, Debug)]
+#[command(author, version, about, long_about = None)]
+struct Args {
+ /// uri of the GTFS RT feed to fetch & display
+ #[arg(long)]
+ url: String,
+}
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let args = Args::parse();
+ let resp = reqwest::get(&args.url)
+ .await?
+ .bytes().await?;
+
+ let proto = FeedMessage::parse_from_bytes(&resp[..])?;
+
+ println!("{}", protobuf::text_format::print_to_string_pretty(&proto));
+ Ok(())
+}
+
diff --git a/src/protos.rs b/src/protos.rs
new file mode 100644
index 0000000..28d29c5
--- /dev/null
+++ b/src/protos.rs
@@ -0,0 +1,4 @@
+
+pub mod protos {
+ include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
+}
diff --git a/src/protos/gtfs-realtime.proto b/src/protos/gtfs-realtime.proto
new file mode 100644
index 0000000..8ee20f0
--- /dev/null
+++ b/src/protos/gtfs-realtime.proto
@@ -0,0 +1,1024 @@
+// Copyright 2015 The GTFS Specifications Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Protocol definition file for GTFS Realtime.
+//
+// GTFS Realtime lets transit agencies provide consumers with realtime
+// information about disruptions to their service (stations closed, lines not
+// operating, important delays etc), location of their vehicles and expected
+// arrival times.
+//
+// This protocol is published at:
+// https://github.com/google/transit/tree/master/gtfs-realtime
+
+syntax = "proto2";
+option java_package = "com.google.transit.realtime";
+package transit_realtime;
+
+// The contents of a feed message.
+// A feed is a continuous stream of feed messages. Each message in the stream is
+// obtained as a response to an appropriate HTTP GET request.
+// A realtime feed is always defined with relation to an existing GTFS feed.
+// All the entity ids are resolved with respect to the GTFS feed.
+// Note that "required" and "optional" as stated in this file refer to Protocol
+// Buffer cardinality, not semantic cardinality. See reference.md at
+// https://github.com/google/transit/tree/master/gtfs-realtime for field
+// semantic cardinality.
+message FeedMessage {
+ // Metadata about this feed and feed message.
+ required FeedHeader header = 1;
+
+ // Contents of the feed.
+ repeated FeedEntity entity = 2;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// Metadata about a feed, included in feed messages.
+message FeedHeader {
+ // Version of the feed specification.
+ // The current version is 2.0. Valid versions are "2.0", "1.0".
+ required string gtfs_realtime_version = 1;
+
+ // Determines whether the current fetch is incremental. Currently,
+ // DIFFERENTIAL mode is unsupported and behavior is unspecified for feeds
+ // that use this mode. There are discussions on the GTFS Realtime mailing
+ // list around fully specifying the behavior of DIFFERENTIAL mode and the
+ // documentation will be updated when those discussions are finalized.
+ enum Incrementality {
+ FULL_DATASET = 0;
+ DIFFERENTIAL = 1;
+ }
+ optional Incrementality incrementality = 2 [default = FULL_DATASET];
+
+ // This timestamp identifies the moment when the content of this feed has been
+ // created (in server time). In POSIX time (i.e., number of seconds since
+ // January 1st 1970 00:00:00 UTC).
+ optional uint64 timestamp = 3;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// A definition (or update) of an entity in the transit feed.
+message FeedEntity {
+ // The ids are used only to provide incrementality support. The id should be
+ // unique within a FeedMessage. Consequent FeedMessages may contain
+ // FeedEntities with the same id. In case of a DIFFERENTIAL update the new
+ // FeedEntity with some id will replace the old FeedEntity with the same id
+ // (or delete it - see is_deleted below).
+ // The actual GTFS entities (e.g. stations, routes, trips) referenced by the
+ // feed must be specified by explicit selectors (see EntitySelector below for
+ // more info).
+ required string id = 1;
+
+ // Whether this entity is to be deleted. Relevant only for incremental
+ // fetches.
+ optional bool is_deleted = 2 [default = false];
+
+ // Data about the entity itself. Exactly one of the following fields must be
+ // present (unless the entity is being deleted).
+ optional TripUpdate trip_update = 3;
+ optional VehiclePosition vehicle = 4;
+ optional Alert alert = 5;
+
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional Shape shape = 6;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+//
+// Entities used in the feed.
+//
+
+// Realtime update of the progress of a vehicle along a trip.
+// Depending on the value of ScheduleRelationship, a TripUpdate can specify:
+// - A trip that proceeds along the schedule.
+// - A trip that proceeds along a route but has no fixed schedule.
+// - A trip that have been added or removed with regard to schedule.
+//
+// The updates can be for future, predicted arrival/departure events, or for
+// past events that already occurred.
+// Normally, updates should get more precise and more certain (see
+// uncertainty below) as the events gets closer to current time.
+// Even if that is not possible, the information for past events should be
+// precise and certain. In particular, if an update points to time in the past
+// but its update's uncertainty is not 0, the client should conclude that the
+// update is a (wrong) prediction and that the trip has not completed yet.
+//
+// Note that the update can describe a trip that is already completed.
+// To this end, it is enough to provide an update for the last stop of the trip.
+// If the time of that is in the past, the client will conclude from that that
+// the whole trip is in the past (it is possible, although inconsequential, to
+// also provide updates for preceding stops).
+// This option is most relevant for a trip that has completed ahead of schedule,
+// but according to the schedule, the trip is still proceeding at the current
+// time. Removing the updates for this trip could make the client assume
+// that the trip is still proceeding.
+// Note that the feed provider is allowed, but not required, to purge past
+// updates - this is one case where this would be practically useful.
+message TripUpdate {
+ // The Trip that this message applies to. There can be at most one
+ // TripUpdate entity for each actual trip instance.
+ // If there is none, that means there is no prediction information available.
+ // It does *not* mean that the trip is progressing according to schedule.
+ required TripDescriptor trip = 1;
+
+ // Additional information on the vehicle that is serving this trip.
+ optional VehicleDescriptor vehicle = 3;
+
+ // Timing information for a single predicted event (either arrival or
+ // departure).
+ // Timing consists of delay and/or estimated time, and uncertainty.
+ // - delay should be used when the prediction is given relative to some
+ // existing schedule in GTFS.
+ // - time should be given whether there is a predicted schedule or not. If
+ // both time and delay are specified, time will take precedence
+ // (although normally, time, if given for a scheduled trip, should be
+ // equal to scheduled time in GTFS + delay).
+ //
+ // Uncertainty applies equally to both time and delay.
+ // The uncertainty roughly specifies the expected error in true delay (but
+ // note, we don't yet define its precise statistical meaning). It's possible
+ // for the uncertainty to be 0, for example for trains that are driven under
+ // computer timing control.
+ message StopTimeEvent {
+ // Delay (in seconds) can be positive (meaning that the vehicle is late) or
+ // negative (meaning that the vehicle is ahead of schedule). Delay of 0
+ // means that the vehicle is exactly on time.
+ optional int32 delay = 1;
+
+ // Event as absolute time.
+ // In Unix time (i.e., number of seconds since January 1st 1970 00:00:00
+ // UTC).
+ optional int64 time = 2;
+
+ // If uncertainty is omitted, it is interpreted as unknown.
+ // If the prediction is unknown or too uncertain, the delay (or time) field
+ // should be empty. In such case, the uncertainty field is ignored.
+ // To specify a completely certain prediction, set its uncertainty to 0.
+ optional int32 uncertainty = 3;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features
+ // and modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+
+ // Realtime update for arrival and/or departure events for a given stop on a
+ // trip. Updates can be supplied for both past and future events.
+ // The producer is allowed, although not required, to drop past events.
+ message StopTimeUpdate {
+ // The update is linked to a specific stop either through stop_sequence or
+ // stop_id, so one of the fields below must necessarily be set.
+ // See the documentation in TripDescriptor for more information.
+
+ // Must be the same as in stop_times.txt in the corresponding GTFS feed.
+ optional uint32 stop_sequence = 1;
+ // Must be the same as in stops.txt in the corresponding GTFS feed.
+ optional string stop_id = 4;
+
+ optional StopTimeEvent arrival = 2;
+ optional StopTimeEvent departure = 3;
+
+ // Expected occupancy after departure from the given stop.
+ // Should be provided only for future stops.
+ // In order to provide departure_occupancy_status without either arrival or
+ // departure StopTimeEvents, ScheduleRelationship should be set to NO_DATA.
+ optional VehiclePosition.OccupancyStatus departure_occupancy_status = 7;
+
+ // The relation between the StopTimeEvents and the static schedule.
+ enum ScheduleRelationship {
+ // The vehicle is proceeding in accordance with its static schedule of
+ // stops, although not necessarily according to the times of the schedule.
+ // At least one of arrival and departure must be provided. If the schedule
+ // for this stop contains both arrival and departure times then so must
+ // this update. Frequency-based trips (GTFS frequencies.txt with exact_times = 0)
+ // should not have a SCHEDULED value and should use UNSCHEDULED instead.
+ SCHEDULED = 0;
+
+ // The stop is skipped, i.e., the vehicle will not stop at this stop.
+ // Arrival and departure are optional.
+ SKIPPED = 1;
+
+ // No StopTimeEvents are given for this stop.
+ // The main intention for this value is to give time predictions only for
+ // part of a trip, i.e., if the last update for a trip has a NO_DATA
+ // specifier, then StopTimeEvents for the rest of the stops in the trip
+ // are considered to be unspecified as well.
+ // Neither arrival nor departure should be supplied.
+ NO_DATA = 2;
+
+ // The vehicle is operating a trip defined in GTFS frequencies.txt with exact_times = 0.
+ // This value should not be used for trips that are not defined in GTFS frequencies.txt,
+ // or trips in GTFS frequencies.txt with exact_times = 1. Trips containing StopTimeUpdates
+ // with ScheduleRelationship=UNSCHEDULED must also set TripDescriptor.ScheduleRelationship=UNSCHEDULED.
+ // NOTE: This field is still experimental, and subject to change. It may be
+ // formally adopted in the future.
+ UNSCHEDULED = 3;
+ }
+ optional ScheduleRelationship schedule_relationship = 5
+ [default = SCHEDULED];
+
+ // Provides the updated values for the stop time.
+ // NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future.
+ message StopTimeProperties {
+ // Supports real-time stop assignments. Refers to a stop_id defined in the GTFS stops.txt.
+ // The new assigned_stop_id should not result in a significantly different trip experience for the end user than
+ // the stop_id defined in GTFS stop_times.txt. In other words, the end user should not view this new stop_id as an
+ // "unusual change" if the new stop was presented within an app without any additional context.
+ // For example, this field is intended to be used for platform assignments by using a stop_id that belongs to the
+ // same station as the stop originally defined in GTFS stop_times.txt.
+ // To assign a stop without providing any real-time arrival or departure predictions, populate this field and set
+ // StopTimeUpdate.schedule_relationship = NO_DATA.
+ // If this field is populated, it is preferred to omit `StopTimeUpdate.stop_id` and use only `StopTimeUpdate.stop_sequence`. If
+ // `StopTimeProperties.assigned_stop_id` and `StopTimeUpdate.stop_id` are populated, `StopTimeUpdate.stop_id` must match `assigned_stop_id`.
+ // Platform assignments should be reflected in other GTFS-realtime fields as well
+ // (e.g., `VehiclePosition.stop_id`).
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string assigned_stop_id = 1;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features
+ // and modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+
+ // Realtime updates for certain properties defined within GTFS stop_times.txt
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional StopTimeProperties stop_time_properties = 6;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features
+ // and modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+
+ // Updates to StopTimes for the trip (both future, i.e., predictions, and in
+ // some cases, past ones, i.e., those that already happened).
+ // The updates must be sorted by stop_sequence, and apply for all the
+ // following stops of the trip up to the next specified one.
+ //
+ // Example 1:
+ // For a trip with 20 stops, a StopTimeUpdate with arrival delay and departure
+ // delay of 0 for stop_sequence of the current stop means that the trip is
+ // exactly on time.
+ //
+ // Example 2:
+ // For the same trip instance, 3 StopTimeUpdates are provided:
+ // - delay of 5 min for stop_sequence 3
+ // - delay of 1 min for stop_sequence 8
+ // - delay of unspecified duration for stop_sequence 10
+ // This will be interpreted as:
+ // - stop_sequences 3,4,5,6,7 have delay of 5 min.
+ // - stop_sequences 8,9 have delay of 1 min.
+ // - stop_sequences 10,... have unknown delay.
+ repeated StopTimeUpdate stop_time_update = 2;
+
+ // The most recent moment at which the vehicle's real-time progress was measured
+ // to estimate StopTimes in the future. When StopTimes in the past are provided,
+ // arrival/departure times may be earlier than this value. In POSIX
+ // time (i.e., the number of seconds since January 1st 1970 00:00:00 UTC).
+ optional uint64 timestamp = 4;
+
+ // The current schedule deviation for the trip. Delay should only be
+ // specified when the prediction is given relative to some existing schedule
+ // in GTFS.
+ //
+ // Delay (in seconds) can be positive (meaning that the vehicle is late) or
+ // negative (meaning that the vehicle is ahead of schedule). Delay of 0
+ // means that the vehicle is exactly on time.
+ //
+ // Delay information in StopTimeUpdates take precedent of trip-level delay
+ // information, such that trip-level delay is only propagated until the next
+ // stop along the trip with a StopTimeUpdate delay value specified.
+ //
+ // Feed providers are strongly encouraged to provide a TripUpdate.timestamp
+ // value indicating when the delay value was last updated, in order to
+ // evaluate the freshness of the data.
+ //
+ // NOTE: This field is still experimental, and subject to change. It may be
+ // formally adopted in the future.
+ optional int32 delay = 5;
+
+ // Defines updated properties of the trip, such as a new shape_id when there is a detour. Or defines the
+ // trip_id, start_date, and start_time of a DUPLICATED trip.
+ // NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future.
+ message TripProperties {
+ // Defines the identifier of a new trip that is a duplicate of an existing trip defined in (CSV) GTFS trips.txt
+ // but will start at a different service date and/or time (defined using the TripProperties.start_date and
+ // TripProperties.start_time fields). See definition of trips.trip_id in (CSV) GTFS. Its value must be different
+ // than the ones used in the (CSV) GTFS. Required if schedule_relationship=DUPLICATED, otherwise this field must not
+ // be populated and will be ignored by consumers.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string trip_id = 1;
+ // Service date on which the DUPLICATED trip will be run, in YYYYMMDD format. Required if
+ // schedule_relationship=DUPLICATED, otherwise this field must not be populated and will be ignored by consumers.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string start_date = 2;
+ // Defines the departure start time of the trip when it’s duplicated. See definition of stop_times.departure_time
+ // in (CSV) GTFS. Scheduled arrival and departure times for the duplicated trip are calculated based on the offset
+ // between the original trip departure_time and this field. For example, if a GTFS trip has stop A with a
+ // departure_time of 10:00:00 and stop B with departure_time of 10:01:00, and this field is populated with the value
+ // of 10:30:00, stop B on the duplicated trip will have a scheduled departure_time of 10:31:00. Real-time prediction
+ // delay values are applied to this calculated schedule time to determine the predicted time. For example, if a
+ // departure delay of 30 is provided for stop B, then the predicted departure time is 10:31:30. Real-time
+ // prediction time values do not have any offset applied to them and indicate the predicted time as provided.
+ // For example, if a departure time representing 10:31:30 is provided for stop B, then the predicted departure time
+ // is 10:31:30. This field is required if schedule_relationship is DUPLICATED, otherwise this field must not be
+ // populated and will be ignored by consumers.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string start_time = 3;
+ // Specifies the shape of the vehicle travel path when the trip shape differs from the shape specified in
+ // (CSV) GTFS or to specify it in real-time when it's not provided by (CSV) GTFS, such as a vehicle that takes differing
+ // paths based on rider demand. See definition of trips.shape_id in (CSV) GTFS. If a shape is neither defined in (CSV) GTFS
+ // nor in real-time, the shape is considered unknown. This field can refer to a shape defined in the (CSV) GTFS in shapes.txt
+ // or a Shape in the (protobuf) real-time feed. The order of stops (stop sequences) for this trip must remain the same as
+ // (CSV) GTFS. Stops that are a part of the original trip but will no longer be made, such as when a detour occurs, should
+ // be marked as schedule_relationship=SKIPPED.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string shape_id = 4;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features
+ // and modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+ optional TripProperties trip_properties = 6;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// Realtime positioning information for a given vehicle.
+message VehiclePosition {
+ // The Trip that this vehicle is serving.
+ // Can be empty or partial if the vehicle can not be identified with a given
+ // trip instance.
+ optional TripDescriptor trip = 1;
+
+ // Additional information on the vehicle that is serving this trip.
+ optional VehicleDescriptor vehicle = 8;
+
+ // Current position of this vehicle.
+ optional Position position = 2;
+
+ // The stop sequence index of the current stop. The meaning of
+ // current_stop_sequence (i.e., the stop that it refers to) is determined by
+ // current_status.
+ // If current_status is missing IN_TRANSIT_TO is assumed.
+ optional uint32 current_stop_sequence = 3;
+ // Identifies the current stop. The value must be the same as in stops.txt in
+ // the corresponding GTFS feed.
+ optional string stop_id = 7;
+
+ enum VehicleStopStatus {
+ // The vehicle is just about to arrive at the stop (on a stop
+ // display, the vehicle symbol typically flashes).
+ INCOMING_AT = 0;
+
+ // The vehicle is standing at the stop.
+ STOPPED_AT = 1;
+
+ // The vehicle has departed and is in transit to the next stop.
+ IN_TRANSIT_TO = 2;
+ }
+ // The exact status of the vehicle with respect to the current stop.
+ // Ignored if current_stop_sequence is missing.
+ optional VehicleStopStatus current_status = 4 [default = IN_TRANSIT_TO];
+
+ // Moment at which the vehicle's position was measured. In POSIX time
+ // (i.e., number of seconds since January 1st 1970 00:00:00 UTC).
+ optional uint64 timestamp = 5;
+
+ // Congestion level that is affecting this vehicle.
+ enum CongestionLevel {
+ UNKNOWN_CONGESTION_LEVEL = 0;
+ RUNNING_SMOOTHLY = 1;
+ STOP_AND_GO = 2;
+ CONGESTION = 3;
+ SEVERE_CONGESTION = 4; // People leaving their cars.
+ }
+ optional CongestionLevel congestion_level = 6;
+
+ // The state of passenger occupancy for the vehicle or carriage.
+ // Individual producers may not publish all OccupancyStatus values. Therefore, consumers
+ // must not assume that the OccupancyStatus values follow a linear scale.
+ // Consumers should represent OccupancyStatus values as the state indicated
+ // and intended by the producer. Likewise, producers must use OccupancyStatus values that
+ // correspond to actual vehicle occupancy states.
+ // For describing passenger occupancy levels on a linear scale, see `occupancy_percentage`.
+ // This field is still experimental, and subject to change. It may be formally adopted in the future.
+ enum OccupancyStatus {
+ // The vehicle or carriage is considered empty by most measures, and has few or no
+ // passengers onboard, but is still accepting passengers.
+ EMPTY = 0;
+
+ // The vehicle or carriage has a large number of seats available.
+ // The amount of free seats out of the total seats available to be
+ // considered large enough to fall into this category is determined at the
+ // discretion of the producer.
+ MANY_SEATS_AVAILABLE = 1;
+
+ // The vehicle or carriage has a relatively small number of seats available.
+ // The amount of free seats out of the total seats available to be
+ // considered small enough to fall into this category is determined at the
+ // discretion of the feed producer.
+ FEW_SEATS_AVAILABLE = 2;
+
+ // The vehicle or carriage can currently accommodate only standing passengers.
+ STANDING_ROOM_ONLY = 3;
+
+ // The vehicle or carriage can currently accommodate only standing passengers
+ // and has limited space for them.
+ CRUSHED_STANDING_ROOM_ONLY = 4;
+
+ // The vehicle or carriage is considered full by most measures, but may still be
+ // allowing passengers to board.
+ FULL = 5;
+
+ // The vehicle or carriage is not accepting passengers, but usually accepts passengers for boarding.
+ NOT_ACCEPTING_PASSENGERS = 6;
+
+ // The vehicle or carriage doesn't have any occupancy data available at that time.
+ NO_DATA_AVAILABLE = 7;
+
+ // The vehicle or carriage is not boardable and never accepts passengers.
+ // Useful for special vehicles or carriages (engine, maintenance carriage, etc…).
+ NOT_BOARDABLE = 8;
+
+ }
+ // If multi_carriage_status is populated with per-carriage OccupancyStatus,
+ // then this field should describe the entire vehicle with all carriages accepting passengers considered.
+ optional OccupancyStatus occupancy_status = 9;
+
+ // A percentage value indicating the degree of passenger occupancy in the vehicle.
+ // The values are represented as an integer without decimals. 0 means 0% and 100 means 100%.
+ // The value 100 should represent the total maximum occupancy the vehicle was designed for,
+ // including both seated and standing capacity, and current operating regulations allow.
+ // The value may exceed 100 if there are more passengers than the maximum designed capacity.
+ // The precision of occupancy_percentage should be low enough that individual passengers cannot be tracked boarding or alighting the vehicle.
+ // If multi_carriage_status is populated with per-carriage occupancy_percentage,
+ // then this field should describe the entire vehicle with all carriages accepting passengers considered.
+ // This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional uint32 occupancy_percentage = 10;
+
+ // Carriage specific details, used for vehicles composed of several carriages
+ // This message/field is still experimental, and subject to change. It may be formally adopted in the future.
+ message CarriageDetails {
+
+ // Identification of the carriage. Should be unique per vehicle.
+ optional string id = 1;
+
+ // User visible label that may be shown to the passenger to help identify
+ // the carriage. Example: "7712", "Car ABC-32", etc...
+ // This message/field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string label = 2;
+
+ // Occupancy status for this given carriage, in this vehicle
+ // This message/field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional OccupancyStatus occupancy_status = 3 [default = NO_DATA_AVAILABLE];
+
+ // Occupancy percentage for this given carriage, in this vehicle.
+ // Follows the same rules as "VehiclePosition.occupancy_percentage"
+ // -1 in case data is not available for this given carriage (as protobuf defaults to 0 otherwise)
+ // This message/field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional int32 occupancy_percentage = 4 [default = -1];
+
+ // Identifies the order of this carriage with respect to the other
+ // carriages in the vehicle's list of CarriageDetails.
+ // The first carriage in the direction of travel must have a value of 1.
+ // The second value corresponds to the second carriage in the direction
+ // of travel and must have a value of 2, and so forth.
+ // For example, the first carriage in the direction of travel has a value of 1.
+ // If the second carriage in the direction of travel has a value of 3,
+ // consumers will discard data for all carriages (i.e., the multi_carriage_details field).
+ // Carriages without data must be represented with a valid carriage_sequence number and the fields
+ // without data should be omitted (alternately, those fields could also be included and set to the "no data" values).
+ // This message/field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional uint32 carriage_sequence = 5;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+
+ // Details of the multiple carriages of this given vehicle.
+ // The first occurrence represents the first carriage of the vehicle,
+ // given the current direction of travel.
+ // The number of occurrences of the multi_carriage_details
+ // field represents the number of carriages of the vehicle.
+ // It also includes non boardable carriages,
+ // like engines, maintenance carriages, etc… as they provide valuable
+ // information to passengers about where to stand on a platform.
+ // This message/field is still experimental, and subject to change. It may be formally adopted in the future.
+ repeated CarriageDetails multi_carriage_details = 11;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// An alert, indicating some sort of incident in the public transit network.
+message Alert {
+ // Time when the alert should be shown to the user. If missing, the
+ // alert will be shown as long as it appears in the feed.
+ // If multiple ranges are given, the alert will be shown during all of them.
+ repeated TimeRange active_period = 1;
+
+ // Entities whose users we should notify of this alert.
+ repeated EntitySelector informed_entity = 5;
+
+ // Cause of this alert. If cause_detail is included, then Cause must also be included.
+ enum Cause {
+ UNKNOWN_CAUSE = 1;
+ OTHER_CAUSE = 2; // Not machine-representable.
+ TECHNICAL_PROBLEM = 3;
+ STRIKE = 4; // Public transit agency employees stopped working.
+ DEMONSTRATION = 5; // People are blocking the streets.
+ ACCIDENT = 6;
+ HOLIDAY = 7;
+ WEATHER = 8;
+ MAINTENANCE = 9;
+ CONSTRUCTION = 10;
+ POLICE_ACTIVITY = 11;
+ MEDICAL_EMERGENCY = 12;
+ }
+ optional Cause cause = 6 [default = UNKNOWN_CAUSE];
+
+ // What is the effect of this problem on the affected entity. If effect_detail is included, then Effect must also be included.
+ enum Effect {
+ NO_SERVICE = 1;
+ REDUCED_SERVICE = 2;
+
+ // We don't care about INsignificant delays: they are hard to detect, have
+ // little impact on the user, and would clutter the results as they are too
+ // frequent.
+ SIGNIFICANT_DELAYS = 3;
+
+ DETOUR = 4;
+ ADDITIONAL_SERVICE = 5;
+ MODIFIED_SERVICE = 6;
+ OTHER_EFFECT = 7;
+ UNKNOWN_EFFECT = 8;
+ STOP_MOVED = 9;
+ NO_EFFECT = 10;
+ ACCESSIBILITY_ISSUE = 11;
+ }
+ optional Effect effect = 7 [default = UNKNOWN_EFFECT];
+
+ // The URL which provides additional information about the alert.
+ optional TranslatedString url = 8;
+
+ // Alert header. Contains a short summary of the alert text as plain-text.
+ optional TranslatedString header_text = 10;
+
+ // Full description for the alert as plain-text. The information in the
+ // description should add to the information of the header.
+ optional TranslatedString description_text = 11;
+
+ // Text for alert header to be used in text-to-speech implementations. This field is the text-to-speech version of header_text.
+ optional TranslatedString tts_header_text = 12;
+
+ // Text for full description for the alert to be used in text-to-speech implementations. This field is the text-to-speech version of description_text.
+ optional TranslatedString tts_description_text = 13;
+
+ // Severity of this alert.
+ enum SeverityLevel {
+ UNKNOWN_SEVERITY = 1;
+ INFO = 2;
+ WARNING = 3;
+ SEVERE = 4;
+ }
+
+ optional SeverityLevel severity_level = 14 [default = UNKNOWN_SEVERITY];
+
+ // TranslatedImage to be displayed along the alert text. Used to explain visually the alert effect of a detour, station closure, etc. The image must enhance the understanding of the alert. Any essential information communicated within the image must also be contained in the alert text.
+ // The following types of images are discouraged : image containing mainly text, marketing or branded images that add no additional information.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional TranslatedImage image = 15;
+
+ // Text describing the appearance of the linked image in the `image` field (e.g., in case the image can't be displayed
+ // or the user can't see the image for accessibility reasons). See the HTML spec for alt image text - https://html.spec.whatwg.org/#alt.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional TranslatedString image_alternative_text = 16;
+
+
+ // Description of the cause of the alert that allows for agency-specific language; more specific than the Cause. If cause_detail is included, then Cause must also be included.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional TranslatedString cause_detail = 17;
+
+ // Description of the effect of the alert that allows for agency-specific language; more specific than the Effect. If effect_detail is included, then Effect must also be included.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional TranslatedString effect_detail = 18;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features
+ // and modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+//
+// Low level data structures used above.
+//
+
+// A time interval. The interval is considered active at time 't' if 't' is
+// greater than or equal to the start time and less than the end time.
+message TimeRange {
+ // Start time, in POSIX time (i.e., number of seconds since January 1st 1970
+ // 00:00:00 UTC).
+ // If missing, the interval starts at minus infinity.
+ optional uint64 start = 1;
+
+ // End time, in POSIX time (i.e., number of seconds since January 1st 1970
+ // 00:00:00 UTC).
+ // If missing, the interval ends at plus infinity.
+ optional uint64 end = 2;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// A position.
+message Position {
+ // Degrees North, in the WGS-84 coordinate system.
+ required float latitude = 1;
+
+ // Degrees East, in the WGS-84 coordinate system.
+ required float longitude = 2;
+
+ // Bearing, in degrees, clockwise from North, i.e., 0 is North and 90 is East.
+ // This can be the compass bearing, or the direction towards the next stop
+ // or intermediate location.
+ // This should not be direction deduced from the sequence of previous
+ // positions, which can be computed from previous data.
+ optional float bearing = 3;
+
+ // Odometer value, in meters.
+ optional double odometer = 4;
+ // Momentary speed measured by the vehicle, in meters per second.
+ optional float speed = 5;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// A descriptor that identifies an instance of a GTFS trip, or all instances of
+// a trip along a route.
+// - To specify a single trip instance, the trip_id (and if necessary,
+// start_time) is set. If route_id is also set, then it should be same as one
+// that the given trip corresponds to.
+// - To specify all the trips along a given route, only the route_id should be
+// set. Note that if the trip_id is not known, then stop sequence ids in
+// TripUpdate are not sufficient, and stop_ids must be provided as well. In
+// addition, absolute arrival/departure times must be provided.
+message TripDescriptor {
+ // The trip_id from the GTFS feed that this selector refers to.
+ // For non frequency-based trips, this field is enough to uniquely identify
+ // the trip. For frequency-based trip, start_time and start_date might also be
+ // necessary. When schedule_relationship is DUPLICATED within a TripUpdate, the trip_id identifies the trip from
+ // static GTFS to be duplicated. When schedule_relationship is DUPLICATED within a VehiclePosition, the trip_id
+ // identifies the new duplicate trip and must contain the value for the corresponding TripUpdate.TripProperties.trip_id.
+ optional string trip_id = 1;
+
+ // The route_id from the GTFS that this selector refers to.
+ optional string route_id = 5;
+
+ // The direction_id from the GTFS feed trips.txt file, indicating the
+ // direction of travel for trips this selector refers to.
+ optional uint32 direction_id = 6;
+
+ // The initially scheduled start time of this trip instance.
+ // When the trip_id corresponds to a non-frequency-based trip, this field
+ // should either be omitted or be equal to the value in the GTFS feed. When
+ // the trip_id correponds to a frequency-based trip, the start_time must be
+ // specified for trip updates and vehicle positions. If the trip corresponds
+ // to exact_times=1 GTFS record, then start_time must be some multiple
+ // (including zero) of headway_secs later than frequencies.txt start_time for
+ // the corresponding time period. If the trip corresponds to exact_times=0,
+ // then its start_time may be arbitrary, and is initially expected to be the
+ // first departure of the trip. Once established, the start_time of this
+ // frequency-based trip should be considered immutable, even if the first
+ // departure time changes -- that time change may instead be reflected in a
+ // StopTimeUpdate.
+ // Format and semantics of the field is same as that of
+ // GTFS/frequencies.txt/start_time, e.g., 11:15:35 or 25:15:35.
+ optional string start_time = 2;
+ // The scheduled start date of this trip instance.
+ // Must be provided to disambiguate trips that are so late as to collide with
+ // a scheduled trip on a next day. For example, for a train that departs 8:00
+ // and 20:00 every day, and is 12 hours late, there would be two distinct
+ // trips on the same time.
+ // This field can be provided but is not mandatory for schedules in which such
+ // collisions are impossible - for example, a service running on hourly
+ // schedule where a vehicle that is one hour late is not considered to be
+ // related to schedule anymore.
+ // In YYYYMMDD format.
+ optional string start_date = 3;
+
+ // The relation between this trip and the static schedule. If a trip is done
+ // in accordance with temporary schedule, not reflected in GTFS, then it
+ // shouldn't be marked as SCHEDULED, but likely as ADDED.
+ enum ScheduleRelationship {
+ // Trip that is running in accordance with its GTFS schedule, or is close
+ // enough to the scheduled trip to be associated with it.
+ SCHEDULED = 0;
+
+ // An extra trip that was added in addition to a running schedule, for
+ // example, to replace a broken vehicle or to respond to sudden passenger
+ // load.
+ // NOTE: Currently, behavior is unspecified for feeds that use this mode. There are discussions on the GTFS GitHub
+ // [(1)](https://github.com/google/transit/issues/106) [(2)](https://github.com/google/transit/pull/221)
+ // [(3)](https://github.com/google/transit/pull/219) around fully specifying or deprecating ADDED trips and the
+ // documentation will be updated when those discussions are finalized.
+ ADDED = 1;
+
+ // A trip that is running with no schedule associated to it (GTFS frequencies.txt exact_times=0).
+ // Trips with ScheduleRelationship=UNSCHEDULED must also set all StopTimeUpdates.ScheduleRelationship=UNSCHEDULED.
+ UNSCHEDULED = 2;
+
+ // A trip that existed in the schedule but was removed.
+ CANCELED = 3;
+
+ // Should not be used - for backwards-compatibility only.
+ REPLACEMENT = 5 [deprecated=true];
+
+ // An extra trip that was added in addition to a running schedule, for example, to replace a broken vehicle or to
+ // respond to sudden passenger load. Used with TripUpdate.TripProperties.trip_id, TripUpdate.TripProperties.start_date,
+ // and TripUpdate.TripProperties.start_time to copy an existing trip from static GTFS but start at a different service
+ // date and/or time. Duplicating a trip is allowed if the service related to the original trip in (CSV) GTFS
+ // (in calendar.txt or calendar_dates.txt) is operating within the next 30 days. The trip to be duplicated is
+ // identified via TripUpdate.TripDescriptor.trip_id. This enumeration does not modify the existing trip referenced by
+ // TripUpdate.TripDescriptor.trip_id - if a producer wants to cancel the original trip, it must publish a separate
+ // TripUpdate with the value of CANCELED. Trips defined in GTFS frequencies.txt with exact_times that is empty or
+ // equal to 0 cannot be duplicated. The VehiclePosition.TripDescriptor.trip_id for the new trip must contain
+ // the matching value from TripUpdate.TripProperties.trip_id and VehiclePosition.TripDescriptor.ScheduleRelationship
+ // must also be set to DUPLICATED.
+ // Existing producers and consumers that were using the ADDED enumeration to represent duplicated trips must follow
+ // the migration guide (https://github.com/google/transit/tree/master/gtfs-realtime/spec/en/examples/migration-duplicated.md)
+ // to transition to the DUPLICATED enumeration.
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ DUPLICATED = 6;
+ }
+ optional ScheduleRelationship schedule_relationship = 4;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// Identification information for the vehicle performing the trip.
+message VehicleDescriptor {
+ // Internal system identification of the vehicle. Should be unique per
+ // vehicle, and can be used for tracking the vehicle as it proceeds through
+ // the system.
+ optional string id = 1;
+
+ // User visible label, i.e., something that must be shown to the passenger to
+ // help identify the correct vehicle.
+ optional string label = 2;
+
+ // The license plate of the vehicle.
+ optional string license_plate = 3;
+
+ enum WheelchairAccessible {
+ // The trip doesn't have information about wheelchair accessibility.
+ // This is the **default** behavior. If the static GTFS contains a
+ // _wheelchair_accessible_ value, it won't be overwritten.
+ NO_VALUE = 0;
+
+ // The trip has no accessibility value present.
+ // This value will overwrite the value from the GTFS.
+ UNKNOWN = 1;
+
+ // The trip is wheelchair accessible.
+ // This value will overwrite the value from the GTFS.
+ WHEELCHAIR_ACCESSIBLE = 2;
+
+ // The trip is **not** wheelchair accessible.
+ // This value will overwrite the value from the GTFS.
+ WHEELCHAIR_INACCESSIBLE = 3;
+ }
+ optional WheelchairAccessible wheelchair_accessible = 4 [default = NO_VALUE];
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// A selector for an entity in a GTFS feed.
+message EntitySelector {
+ // The values of the fields should correspond to the appropriate fields in the
+ // GTFS feed.
+ // At least one specifier must be given. If several are given, then the
+ // matching has to apply to all the given specifiers.
+ optional string agency_id = 1;
+ optional string route_id = 2;
+ // corresponds to route_type in GTFS.
+ optional int32 route_type = 3;
+ optional TripDescriptor trip = 4;
+ optional string stop_id = 5;
+ // Corresponds to trip direction_id in GTFS trips.txt. If provided the
+ // route_id must also be provided.
+ optional uint32 direction_id = 6;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// An internationalized message containing per-language versions of a snippet of
+// text or a URL.
+// One of the strings from a message will be picked up. The resolution proceeds
+// as follows:
+// 1. If the UI language matches the language code of a translation,
+// the first matching translation is picked.
+// 2. If a default UI language (e.g., English) matches the language code of a
+// translation, the first matching translation is picked.
+// 3. If some translation has an unspecified language code, that translation is
+// picked.
+message TranslatedString {
+ message Translation {
+ // A UTF-8 string containing the message.
+ required string text = 1;
+ // BCP-47 language code. Can be omitted if the language is unknown or if
+ // no i18n is done at all for the feed. At most one translation is
+ // allowed to have an unspecified language tag.
+ optional string language = 2;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+ // At least one translation must be provided.
+ repeated Translation translation = 1;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// An internationalized image containing per-language versions of a URL linking to an image
+// along with meta information
+// Only one of the images from a message will be retained by consumers. The resolution proceeds
+// as follows:
+// 1. If the UI language matches the language code of a translation,
+// the first matching translation is picked.
+// 2. If a default UI language (e.g., English) matches the language code of a
+// translation, the first matching translation is picked.
+// 3. If some translation has an unspecified language code, that translation is
+// picked.
+// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+message TranslatedImage {
+ message LocalizedImage {
+ // String containing an URL linking to an image
+ // The image linked must be less than 2MB.
+ // If an image changes in a significant enough way that an update is required on the consumer side, the producer must update the URL to a new one.
+ // The URL should be a fully qualified URL that includes http:// or https://, and any special characters in the URL must be correctly escaped. See the following http://www.w3.org/Addressing/URL/4_URI_Recommentations.html for a description of how to create fully qualified URL values.
+ required string url = 1;
+
+ // IANA media type as to specify the type of image to be displayed.
+ // The type must start with "image/"
+ required string media_type = 2;
+
+ // BCP-47 language code. Can be omitted if the language is unknown or if
+ // no i18n is done at all for the feed. At most one translation is
+ // allowed to have an unspecified language tag.
+ optional string language = 3;
+
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+ }
+ // At least one localized image must be provided.
+ repeated LocalizedImage localized_image = 1;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}
+
+// Describes the physical path that a vehicle takes when it's not part of the (CSV) GTFS,
+// such as for a detour. Shapes belong to Trips, and consist of a sequence of shape points.
+// Tracing the points in order provides the path of the vehicle. Shapes do not need to intercept
+// the location of Stops exactly, but all Stops on a trip should lie within a small distance of
+// the shape for that trip, i.e. close to straight line segments connecting the shape points
+// NOTE: This message is still experimental, and subject to change. It may be formally adopted in the future.
+message Shape {
+ // Identifier of the shape. Must be different than any shape_id defined in the (CSV) GTFS.
+ // This field is required as per reference.md, but needs to be specified here optional because "Required is Forever"
+ // See https://developers.google.com/protocol-buffers/docs/proto#specifying_field_rules
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string shape_id = 1;
+
+ // Encoded polyline representation of the shape. This polyline must contain at least two points.
+ // For more information about encoded polylines, see https://developers.google.com/maps/documentation/utilities/polylinealgorithm
+ // This field is required as per reference.md, but needs to be specified here optional because "Required is Forever"
+ // See https://developers.google.com/protocol-buffers/docs/proto#specifying_field_rules
+ // NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
+ optional string encoded_polyline = 2;
+
+ // The extensions namespace allows 3rd-party developers to extend the
+ // GTFS Realtime Specification in order to add and evaluate new features and
+ // modifications to the spec.
+ extensions 1000 to 1999;
+
+ // The following extension IDs are reserved for private use by any organization.
+ extensions 9000 to 9999;
+}