mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-05-23 10:48:06 +00:00
Compare commits
3 commits
d53cc21648
...
6dbd11614a
Author | SHA1 | Date | |
---|---|---|---|
6dbd11614a | |||
953e3747f2 | |||
16c751a594 |
572
.gitlab-ci.yml
572
.gitlab-ci.yml
|
@ -59,526 +59,80 @@ variables:
|
||||||
0.22=0.22
|
0.22=0.22
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- "trigger"
|
|
||||||
- "container-base"
|
|
||||||
- "container-final"
|
|
||||||
- "lint"
|
|
||||||
- "test"
|
- "test"
|
||||||
- "extras"
|
|
||||||
- "deploy"
|
|
||||||
|
|
||||||
# This is an empty job that is used to trigger the pipeline.
|
.macos:arm64:
|
||||||
trigger:
|
image: "registry.freedesktop.org/gstreamer/cerbero/macos-arm64/14-sonoma:2023-10-25.2"
|
||||||
image: alpine:latest
|
tags:
|
||||||
stage: 'trigger'
|
- 'gst-mac-arm'
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
tags: [ 'placeholder-job' ]
|
|
||||||
script:
|
|
||||||
- echo "Trigger job done, now running the pipeline."
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
# If the MR is assigned to the Merge bot, trigger the pipeline automatically
|
|
||||||
- if: '$CI_MERGE_REQUEST_ASSIGNEES == "gstreamer-merge-bot"'
|
|
||||||
# Require explicit action to trigger tests post merge
|
|
||||||
- if: '$CI_PROJECT_NAMESPACE == "gstreamer" && $CI_COMMIT_BRANCH == "main"'
|
|
||||||
when: 'manual'
|
|
||||||
# When the assignee isn't the merge bot, require an explicit action to trigger the pipeline
|
|
||||||
# to avoid wasting CI resources
|
|
||||||
- if: '$CI_MERGE_REQUEST_ASSIGNEES != "gstreamer-merge-bot"'
|
|
||||||
when: 'manual'
|
|
||||||
allow_failure: false
|
|
||||||
|
|
||||||
.debian:12:
|
.macos:arm64-stable:
|
||||||
needs: []
|
extends: .macos:arm64
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: 'bookworm-slim'
|
|
||||||
before_script:
|
|
||||||
- source ./ci/env.sh
|
|
||||||
- mkdir .cargo && echo -e "[net]\ngit-fetch-with-cli = true" > .cargo/config
|
|
||||||
|
|
||||||
.debian:12-base:
|
|
||||||
extends: .debian:12
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_TAG: 'base-$GST_RS_IMG_TAG'
|
|
||||||
|
|
||||||
.debian:12-stable:
|
|
||||||
extends: .debian:12
|
|
||||||
variables:
|
|
||||||
RUST_IMAGE_FULL: "1"
|
|
||||||
FDO_DISTRIBUTION_TAG: '$GST_RS_STABLE-$GST_RS_IMG_TAG'
|
|
||||||
FDO_DISTRIBUTION_EXEC: 'bash ci/install-rust.sh $GST_RS_STABLE $RUST_IMAGE_FULL'
|
|
||||||
|
|
||||||
.debian:12-msrv:
|
|
||||||
extends: .debian:12
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_TAG: '$GST_RS_MSRV-$GST_RS_IMG_TAG'
|
|
||||||
FDO_DISTRIBUTION_EXEC: 'bash ci/install-rust.sh $GST_RS_MSRV $RUST_IMAGE_FULL'
|
|
||||||
|
|
||||||
.debian:12-nightly:
|
|
||||||
extends: .debian:12
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_TAG: 'nightly-$GST_RS_IMG_TAG'
|
|
||||||
FDO_DISTRIBUTION_EXEC: 'bash ci/install-rust.sh nightly $RUST_IMAGE_FULL'
|
|
||||||
|
|
||||||
.build-base-image:
|
|
||||||
extends:
|
|
||||||
- .fdo.container-build@debian
|
|
||||||
stage: container-base
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_PACKAGES: >-
|
|
||||||
build-essential curl python3-setuptools libglib2.0-dev libxml2-dev
|
|
||||||
libdrm-dev libegl1-mesa-dev libgl1-mesa-dev libgbm-dev libgles2-mesa-dev
|
|
||||||
libgl1-mesa-dri libegl-dev libgl1-mesa-glx libwayland-egl1-mesa xz-utils
|
|
||||||
libssl-dev git wget ca-certificates ninja-build python3-pip flex bison
|
|
||||||
libglib2.0-dev libx11-dev libx11-xcb-dev libsoup2.4-dev libvorbis-dev
|
|
||||||
libogg-dev libtheora-dev libmatroska-dev libvpx-dev libopus-dev
|
|
||||||
libgraphene-1.0-dev libjpeg-dev libwayland-dev wayland-protocols
|
|
||||||
python3-gi libavcodec-dev libavformat-dev libavutil-dev libavfilter-dev
|
|
||||||
libswscale-dev yasm libx264-dev libfontconfig-dev libfreetype-dev
|
|
||||||
libxkbcommon-dev libxi-dev libxcb-render0-dev libxcb-shm0-dev
|
|
||||||
libxcb1-dev libxext-dev libxrender-dev libxrandr-dev libxcursor-dev
|
|
||||||
libxdamage-dev libxfixes-dev libxinerama-dev libgudev-1.0-dev
|
|
||||||
libpango1.0-dev libcairo2-dev libjson-glib-dev libgdk-pixbuf-2.0-dev
|
|
||||||
libtiff-dev libpng-dev libjpeg-dev libepoxy-dev libsass-dev sassc
|
|
||||||
libcsound64-dev llvm clang nasm libsodium-dev libwebp-dev
|
|
||||||
libflac-dev
|
|
||||||
FDO_DISTRIBUTION_EXEC: >-
|
|
||||||
bash ci/install-gst.sh &&
|
|
||||||
bash ci/install-dav1d.sh &&
|
|
||||||
pip3 install --break-system-packages git+http://gitlab.freedesktop.org/freedesktop/ci-templates &&
|
|
||||||
pip3 install --break-system-packages tomli
|
|
||||||
|
|
||||||
.build-final-image:
|
|
||||||
extends:
|
|
||||||
- .fdo.container-build@debian
|
|
||||||
stage: container-final
|
|
||||||
variables:
|
|
||||||
FDO_BASE_IMAGE: '$CI_REGISTRY_IMAGE/debian/bookworm-slim:base-$GST_RS_IMG_TAG'
|
|
||||||
|
|
||||||
build-base:
|
|
||||||
extends:
|
|
||||||
- .build-base-image
|
|
||||||
- .debian:12-base
|
|
||||||
|
|
||||||
build-stable:
|
|
||||||
needs: ["build-base"]
|
|
||||||
extends:
|
|
||||||
- .build-final-image
|
|
||||||
- .debian:12-stable
|
|
||||||
|
|
||||||
build-msrv:
|
|
||||||
needs: ["build-base"]
|
|
||||||
extends:
|
|
||||||
- .build-final-image
|
|
||||||
- .debian:12-msrv
|
|
||||||
|
|
||||||
build-nightly:
|
|
||||||
needs: ["build-base"]
|
|
||||||
extends:
|
|
||||||
- .build-final-image
|
|
||||||
- .debian:12-nightly
|
|
||||||
|
|
||||||
update-nightly:
|
|
||||||
extends: build-nightly
|
|
||||||
rules:
|
|
||||||
- if: $UPDATE_NIGHTLY == "1"
|
|
||||||
variables:
|
|
||||||
FDO_FORCE_REBUILD: 1
|
|
||||||
|
|
||||||
.dist-debian-container:
|
|
||||||
extends:
|
|
||||||
- .fdo.distribution-image@debian
|
|
||||||
after_script:
|
after_script:
|
||||||
- rm -rf target
|
- rm -rf target
|
||||||
|
|
||||||
.img-stable:
|
before_script:
|
||||||
extends:
|
- CI=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
- .debian:12-stable
|
- (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> $HOME/.zprofile
|
||||||
- .dist-debian-container
|
- eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||||
|
|
||||||
.img-msrv:
|
- CI=1 brew install pkg-config
|
||||||
extends:
|
|
||||||
- .debian:12-msrv
|
|
||||||
- .dist-debian-container
|
|
||||||
|
|
||||||
.img-nightly:
|
- export GST_VERSION=1.24.2
|
||||||
extends:
|
- curl --proto '=https' --tlsv1.2 -o gstreamer-1.0-${GST_VERSION}-universal.pkg -sSf https://gstreamer.freedesktop.org/data/pkg/osx/${GST_VERSION}/gstreamer-1.0-${GST_VERSION}-universal.pkg
|
||||||
- .debian:12-nightly
|
- curl --proto '=https' --tlsv1.2 -o gstreamer-1.0-devel-${GST_VERSION}-universal.pkg -sSf https://gstreamer.freedesktop.org/data/pkg/osx/${GST_VERSION}/gstreamer-1.0-devel-${GST_VERSION}-universal.pkg
|
||||||
- .dist-debian-container
|
- sudo installer -pkg gstreamer-1.0-${GST_VERSION}-universal.pkg -target /
|
||||||
|
- sudo installer -pkg gstreamer-1.0-devel-${GST_VERSION}-universal.pkg -target /
|
||||||
|
- export PKG_CONFIG_PATH=/Library/Frameworks/GStreamer.framework/Versions/1.0/lib/pkgconfig:$PKG_CONFIG_PATH
|
||||||
|
- export DYLD_FALLBACK_LIBRARY_PATH=/Library/Frameworks/GStreamer.framework/Versions/1.0/lib:$DYLD_FALLBACK_LIBRARY_PATH
|
||||||
|
|
||||||
|
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||||
|
- echo -e "[net]\ngit-fetch-with-cli = true" > $HOME/.cargo/config
|
||||||
|
|
||||||
|
- source "$HOME/.cargo/env"
|
||||||
|
|
||||||
.cargo_test_var: &cargo_test
|
test macos-arm64 stable:
|
||||||
- ./ci/run-cargo-test.sh
|
extends: '.macos:arm64-stable'
|
||||||
|
|
||||||
.cargo test:
|
|
||||||
stage: "test"
|
|
||||||
script:
|
|
||||||
- *cargo_test
|
|
||||||
|
|
||||||
test msrv:
|
|
||||||
extends:
|
|
||||||
- '.cargo test'
|
|
||||||
- .img-msrv
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-msrv'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
test stable:
|
|
||||||
extends:
|
|
||||||
- '.cargo test'
|
|
||||||
- .img-stable
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
test stable all-features:
|
|
||||||
variables:
|
|
||||||
ALL_FEATURES: 'yes'
|
|
||||||
EXAMPLES_TUTORIALS: 'yes'
|
|
||||||
extends:
|
|
||||||
- '.cargo test'
|
|
||||||
- .img-stable
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
|
|
||||||
test nightly:
|
|
||||||
allow_failure: true
|
|
||||||
extends:
|
|
||||||
- '.cargo test'
|
|
||||||
- .img-nightly
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-nightly'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
|
|
||||||
test nightly all-features:
|
|
||||||
allow_failure: true
|
|
||||||
variables:
|
|
||||||
ALL_FEATURES: 'yes'
|
|
||||||
EXAMPLES_TUTORIALS: 'yes'
|
|
||||||
extends:
|
|
||||||
- '.cargo test'
|
|
||||||
- .img-nightly
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-nightly'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
.cargo test sys:
|
|
||||||
stage: "test"
|
|
||||||
script:
|
|
||||||
- ./ci/run-sys-cargo-test.sh
|
|
||||||
|
|
||||||
test stable sys:
|
|
||||||
extends:
|
|
||||||
- '.cargo test sys'
|
|
||||||
- .img-stable
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
test msrv sys:
|
|
||||||
extends:
|
|
||||||
- '.cargo test sys'
|
|
||||||
- .img-msrv
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-msrv'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
test nightly sys:
|
|
||||||
extends:
|
|
||||||
- '.cargo test sys'
|
|
||||||
- .img-nightly
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-nightly'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
rustfmt:
|
|
||||||
extends: .img-stable
|
|
||||||
stage: "lint"
|
|
||||||
tags: [ 'placeholder-job' ]
|
|
||||||
script:
|
|
||||||
- cargo fmt --version
|
|
||||||
- cargo fmt -- --color=always --check
|
|
||||||
needs:
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
check commits:
|
|
||||||
extends: .img-stable
|
|
||||||
stage: "lint"
|
|
||||||
tags: [ 'placeholder-job' ]
|
|
||||||
script:
|
|
||||||
- ci-fairy check-commits --textwidth 0 --no-signed-off-by
|
|
||||||
needs:
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
typos:
|
|
||||||
extends: .img-stable
|
|
||||||
stage: "lint"
|
|
||||||
tags: [ 'placeholder-job' ]
|
|
||||||
script:
|
|
||||||
- typos
|
|
||||||
needs:
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
|
|
||||||
clippy:
|
|
||||||
extends: .img-stable
|
|
||||||
stage: 'extras'
|
|
||||||
variables:
|
|
||||||
CLIPPY_LINTS: -D warnings -W unknown-lints
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
script:
|
|
||||||
- ./ci/run-clippy.sh
|
|
||||||
|
|
||||||
deny:
|
|
||||||
extends: .img-stable
|
|
||||||
stage: 'extras'
|
|
||||||
needs:
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
script:
|
|
||||||
- cargo update --color=always
|
|
||||||
- cargo deny --color=always --workspace --all-features check all
|
|
||||||
|
|
||||||
gir-checks:
|
|
||||||
variables:
|
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
extends: .img-stable
|
|
||||||
stage: 'extras'
|
|
||||||
tags: [ 'placeholder-job' ]
|
|
||||||
needs:
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
script:
|
|
||||||
- git submodule update --checkout
|
|
||||||
- python3 ci/gir-checks.py
|
|
||||||
|
|
||||||
outdated:
|
|
||||||
extends: .img-stable
|
|
||||||
stage: 'extras'
|
|
||||||
needs:
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
script:
|
|
||||||
- cargo update --color=always
|
|
||||||
- cargo outdated --color=always --root-deps-only --exit-code 1 -v
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
allow_failure: true
|
|
||||||
extends:
|
|
||||||
- '.cargo test'
|
|
||||||
- .img-stable
|
|
||||||
stage: 'extras'
|
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'build-stable'
|
|
||||||
artifacts: false
|
|
||||||
variables:
|
|
||||||
ALL_FEATURES: 'yes'
|
|
||||||
RUSTFLAGS: "-Cinstrument-coverage"
|
|
||||||
LLVM_PROFILE_FILE: "gstreamer-rs-%p-%m.profraw"
|
|
||||||
script:
|
|
||||||
- *cargo_test
|
|
||||||
# generate html report
|
|
||||||
- grcov . --binary-path ./target/debug/ -s . -t html --branch --ignore-not-existing --ignore "*target*" --ignore "*/sys/*" --ignore "examples/*" --ignore "tutorials/*" --ignore "*/build.rs" -o ./coverage/
|
|
||||||
# generate cobertura report for gitlab integration
|
|
||||||
- grcov . --binary-path ./target/debug/ -s . -t cobertura --branch --ignore-not-existing --ignore "*target*" --ignore "*/sys/*" --ignore "examples/*" --ignore "tutorials/*" --ignore "*/build.rs" -o coverage.xml
|
|
||||||
# output coverage summary for gitlab parsing.
|
|
||||||
# TODO: use grcov once https://github.com/mozilla/grcov/issues/556 is fixed
|
|
||||||
- grep % coverage/index.html | head -1 ; true
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- 'coverage'
|
|
||||||
reports:
|
|
||||||
coverage_report:
|
|
||||||
coverage_format: cobertura
|
|
||||||
path: coverage.xml
|
|
||||||
|
|
||||||
doc-stripping:
|
|
||||||
variables:
|
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
extends: .img-nightly
|
|
||||||
stage: 'extras'
|
|
||||||
needs:
|
|
||||||
- job: 'build-nightly'
|
|
||||||
artifacts: false
|
|
||||||
script:
|
|
||||||
- git submodule update --checkout
|
|
||||||
- PATH=~/.cargo/bin/:$PATH ./generator.py --gir-files-directories gir-files gst-gir-files --embed-docs
|
|
||||||
- PATH=~/.cargo/bin/:$PATH ./generator.py --gir-files-directories gir-files gst-gir-files --strip-docs
|
|
||||||
- git diff --quiet || (echo 'Files changed after running `rustdoc-stripper -s`, make sure all documentation is protected with `// rustdoc-stripper-ignore-next`!'; git diff; false)
|
|
||||||
|
|
||||||
regen-check:
|
|
||||||
variables:
|
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
extends: .img-nightly
|
|
||||||
stage: 'extras'
|
|
||||||
needs:
|
|
||||||
- job: 'build-nightly'
|
|
||||||
artifacts: false
|
|
||||||
script:
|
|
||||||
- git submodule update --checkout
|
|
||||||
- PATH=~/.cargo/bin/:$PATH ./generator.py --gir-files-directories gir-files gst-gir-files --yes
|
|
||||||
- git diff --quiet || (echo 'Files changed after running `generator.py`, make sure all submodules and generated files are in the correct version!'; git diff; false)
|
|
||||||
|
|
||||||
docs:
|
|
||||||
variables:
|
|
||||||
GIT_SUBMODULE_STRATEGY: recursive
|
|
||||||
extends: .img-nightly
|
|
||||||
stage: 'extras'
|
|
||||||
needs:
|
|
||||||
- job: 'build-nightly'
|
|
||||||
artifacts: false
|
|
||||||
script:
|
|
||||||
- git submodule update --checkout
|
|
||||||
- curl --proto '=https' --tlsv1.2 -sSf -o gir-rustdoc.py
|
|
||||||
https://gitlab.gnome.org/World/Rust/gir-rustdoc/-/raw/main/gir-rustdoc.py
|
|
||||||
- chmod +x gir-rustdoc.py
|
|
||||||
- PATH=~/.cargo/bin/:$PATH ./generator.py --gir-files-directories gir-files gst-gir-files --embed-docs --no-fmt
|
|
||||||
- |
|
|
||||||
RUSTDOCFLAGS="$RUST_DOCS_FLAGS"
|
|
||||||
RUSTFLAGS="--cfg docsrs"
|
|
||||||
eval $(./gir-rustdoc.py pre-docs)
|
|
||||||
cargo +nightly doc --workspace --exclude examples --exclude tutorials --all-features --color=always --no-deps
|
|
||||||
- mv target/doc docs
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- 'docs'
|
|
||||||
|
|
||||||
# https://docs.gitlab.com/ee/user/project/pages/#how-it-works
|
|
||||||
# GitLab automatically deploys the `public/` folder from an
|
|
||||||
# artifact generated by the job named `pages`. This step
|
|
||||||
# re-uses the docs from the build-test `docs` step above.
|
|
||||||
pages:
|
|
||||||
extends: .img-nightly
|
|
||||||
stage: 'deploy'
|
|
||||||
needs: [ 'docs' ]
|
|
||||||
interruptible: false
|
|
||||||
script:
|
|
||||||
- curl --proto '=https' --tlsv1.2 -sSf -o gir-rustdoc.py
|
|
||||||
https://gitlab.gnome.org/World/Rust/gir-rustdoc/-/raw/main/gir-rustdoc.py
|
|
||||||
- chmod +x gir-rustdoc.py
|
|
||||||
- ./gir-rustdoc.py html-index
|
|
||||||
# development docs
|
|
||||||
- mkdir public/git
|
|
||||||
- mv docs public/git/docs
|
|
||||||
# stable docs
|
|
||||||
- ./gir-rustdoc.py docs-from-artifacts
|
|
||||||
- ls public/
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- 'public'
|
|
||||||
rules:
|
|
||||||
- if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH) && ($CI_PROJECT_NAMESPACE == $NAMESPACE)
|
|
||||||
when: 'manual'
|
|
||||||
|
|
||||||
|
|
||||||
.windows rust docker build:
|
|
||||||
stage: 'container-final'
|
|
||||||
timeout: '2h'
|
|
||||||
needs: []
|
|
||||||
variables:
|
|
||||||
# Unlike the buildah/linux jobs, this file
|
|
||||||
# needs to be relative to windows-docker/ subdir
|
|
||||||
# as it makes life easier in the powershell script
|
|
||||||
#
|
|
||||||
# We also don't need a CONTEXT_DIR var as its also
|
|
||||||
# hardcoded to be windows-docker/
|
|
||||||
DOCKERFILE: 'ci/windows-docker/Dockerfile'
|
|
||||||
GST_UPSTREAM_BRANCH: 'main'
|
|
||||||
tags:
|
|
||||||
- 'windows'
|
|
||||||
- 'shell'
|
|
||||||
- '2022'
|
|
||||||
script:
|
|
||||||
# We need to pass an array and to resolve the env vars, so we can't use a variable:
|
|
||||||
- $DOCKER_BUILD_ARGS = @("--build-arg", "DEFAULT_BRANCH=$GST_UPSTREAM_BRANCH", "--build-arg", "RUST_VERSION=$RUST_VERSION")
|
|
||||||
|
|
||||||
- "& ci/windows-docker/container.ps1 $CI_REGISTRY $CI_REGISTRY_USER $CI_REGISTRY_PASSWORD $RUST_IMAGE $RUST_UPSTREAM_IMAGE $DOCKERFILE"
|
|
||||||
- |
|
|
||||||
if (!($?)) {
|
|
||||||
echo "Failed to build the image"
|
|
||||||
Exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
windows rust docker stable:
|
|
||||||
extends: '.windows rust docker build'
|
|
||||||
variables:
|
|
||||||
RUST_IMAGE: !reference [variables, "WINDOWS_RUST_STABLE_IMAGE"]
|
|
||||||
RUST_UPSTREAM_IMAGE: !reference [variables, "WINDOWS_RUST_STABLE_UPSTREAM_IMAGE"]
|
|
||||||
RUST_VERSION: !reference [variables, "GST_RS_STABLE"]
|
|
||||||
|
|
||||||
windows rust docker msrv:
|
|
||||||
extends: '.windows rust docker build'
|
|
||||||
when: 'manual'
|
|
||||||
variables:
|
|
||||||
RUST_IMAGE: !reference [variables, "WINDOWS_RUST_MINIMUM_IMAGE"]
|
|
||||||
RUST_UPSTREAM_IMAGE: !reference [variables, "WINDOWS_RUST_MINIMUM_UPSTREAM_IMAGE"]
|
|
||||||
RUST_VERSION: !reference [variables, "GST_RS_MSRV"]
|
|
||||||
|
|
||||||
.msvc2019 build:
|
|
||||||
stage: 'test'
|
stage: 'test'
|
||||||
tags:
|
#needs:
|
||||||
- 'docker'
|
# - 'trigger'
|
||||||
- 'windows'
|
|
||||||
- '2022'
|
|
||||||
script:
|
script:
|
||||||
# Skip -sys tests as they don't work
|
- rustc --version
|
||||||
# https://github.com/gtk-rs/gtk3-rs/issues/54
|
|
||||||
#
|
|
||||||
# We need to build each crate separately to avoid crates like -egl,-wayland etc on windows
|
|
||||||
- cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=amd64 &&
|
|
||||||
powershell ./ci/run_windows_tests.ps1"
|
|
||||||
|
|
||||||
- |
|
# Package exclusion list:
|
||||||
if (!$?) {
|
# * examples & tutorials are handled separately.
|
||||||
Write-Host "Tests Failed!"
|
# * gstreamer-editing-services-sys, gstreamer-rtp-sys ABI tests fail.
|
||||||
Exit 1
|
# * FIXME check some gl support?
|
||||||
}
|
- export EXCLUSION_LIST=(examples tutorials gstreamer-editing-services-sys gstreamer-gl \
|
||||||
|
gstreamer-gl-sys gstreamer-gl-egl gstreamer-gl-egl-sys gstreamer-gl-wayland \
|
||||||
|
gstreamer-gl-wayland-sys gstreamer-gl-x11 gstreamer-gl-x11-sys gstreamer-rtp-sys)
|
||||||
|
- export EXCLUDE_ARGS=(`for p in ${EXCLUSION_LIST[@]}; do printf " --exclude %s" $p; done`)
|
||||||
|
|
||||||
test windows msrv:
|
- cargo build --locked --workspace ${EXCLUDE_ARGS[@]} --all-targets --color=always
|
||||||
image: $WINDOWS_RUST_MINIMUM_IMAGE
|
- G_DEBUG=fatal_warnings cargo test --locked --workspace ${EXCLUDE_ARGS[@]} --all-targets --color=always
|
||||||
needs:
|
|
||||||
- job: 'trigger'
|
|
||||||
artifacts: false
|
|
||||||
- job: 'windows rust docker msrv'
|
|
||||||
artifacts: false
|
|
||||||
extends: '.msvc2019 build'
|
|
||||||
|
|
||||||
test windows stable:
|
# --all-features
|
||||||
needs:
|
- cargo build --locked --workspace ${EXCLUDE_ARGS[@]} --all-targets --all-features --color=always
|
||||||
- job: 'trigger'
|
- G_DEBUG=fatal_warnings cargo test --locked --workspace ${EXCLUDE_ARGS[@]} --all-targets --all-features --color=always
|
||||||
artifacts: false
|
|
||||||
- job: 'windows rust docker stable'
|
# --no-default-features
|
||||||
artifacts: false
|
- cargo build --keep-going --locked --workspace ${EXCLUDE_ARGS[@]} --all-targets --no-default-features --color=always
|
||||||
image: "$WINDOWS_RUST_STABLE_IMAGE"
|
- G_DEBUG=fatal_warnings cargo test --locked --workspace ${EXCLUDE_ARGS[@]} --all-targets --no-default-features --color=always
|
||||||
extends: '.msvc2019 build'
|
|
||||||
|
# examples
|
||||||
|
# Excluding anything gl, fd_allocator & d3d11videosink
|
||||||
|
- export EXAMPLE_FEATURES="rtsp-server gst-rtsp-server/v1_22 rtsp-server-record pango-cairo"
|
||||||
|
- EXAMPLE_FEATURES+=" overlay-composition allocators gst-play gst-player ges image cairo-rs"
|
||||||
|
- EXAMPLE_FEATURES+=" gst-video/v1_18"
|
||||||
|
- export INCLUSION_LIST=(appsink appsrc custom_events custom_meta decodebin debug_ringbuffer \
|
||||||
|
encodebin events iterator launch_glib_main launch transmux pad_probes play playbin player \
|
||||||
|
queries rtpfecclient rtpfecserver rtsp-server rtsp-server-subclass rtsp-server-custom-auth \
|
||||||
|
tagsetter toc futures glib-futures rtsp-server-record discoverer pango-cairo \
|
||||||
|
overlay-composition ges subclass video_converter thumbnail cairo_compositor \
|
||||||
|
audio_multichannel_interleave)
|
||||||
|
- export INCLUDE_ARGS=(`for p in ${INCLUSION_LIST[@]}; do printf " --bin %s" $p; done`)
|
||||||
|
- cargo build --locked --color=always -p examples ${INCLUDE_ARGS[@]} --features="${EXAMPLE_FEATURES}"
|
||||||
|
|
||||||
|
# tutorials
|
||||||
|
# - cargo build --locked --color=always -p tutorials --bins
|
||||||
|
- cargo build --keep-going --locked --color=always -p tutorials --bins
|
||||||
|
|
|
@ -56,6 +56,8 @@ impl GhostPad {
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a new [`GhostPad`] with an automatically generated name.
|
/// Creates a new [`GhostPad`] with an automatically generated name.
|
||||||
///
|
///
|
||||||
|
/// The [`Pad`] will be assigned the usual `gst::Object` generated unique name.
|
||||||
|
///
|
||||||
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
/// and define options.
|
/// and define options.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
||||||
|
@ -65,10 +67,7 @@ impl GhostPad {
|
||||||
}
|
}
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a [`PadBuilder`](crate::PadBuilder) for a [`PadBuilder`] with an automatically generated name.
|
/// Creates a [`PadBuilder`](crate::PadBuilder) with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
|
||||||
/// to specify a different name.
|
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
||||||
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -82,12 +81,15 @@ impl GhostPad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `GhostPad` will automatically be named after the `name_template`.
|
/// the `GhostPad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
|
/// and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
|
||||||
/// and define options.
|
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
||||||
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -103,6 +105,9 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
||||||
/// to specify a different name.
|
/// to specify a different name.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
||||||
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -116,12 +121,15 @@ impl GhostPad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `GhostPad` will automatically be named after the `name_template`.
|
/// the `GhostPad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
|
/// and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
|
||||||
/// and define options.
|
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
||||||
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -137,6 +145,9 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
||||||
/// to specify a different name.
|
/// to specify a different name.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
||||||
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -150,6 +161,9 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`GhostPad::builder_with_target()`] to get a [`PadBuilder`](crate::PadBuilder)
|
/// Use [`GhostPad::builder_with_target()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
/// and define options.
|
/// and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new")]
|
#[doc(alias = "gst_ghost_pad_new")]
|
||||||
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
target: &P,
|
target: &P,
|
||||||
|
@ -165,13 +179,15 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
||||||
/// to specify a different name.
|
/// to specify a different name.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
||||||
pub fn builder_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn builder_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
target: &P,
|
target: &P,
|
||||||
) -> Result<PadBuilder<Self>, glib::BoolError> {
|
) -> Result<PadBuilder<Self>, glib::BoolError> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
let mut builder = Self::builder(target.direction());
|
let builder = Self::builder(target.direction());
|
||||||
builder.needs_specific_name = true;
|
|
||||||
builder.with_target(target)
|
builder.with_target(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +202,9 @@ impl GhostPad {
|
||||||
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
||||||
/// if it is compatible. Otherwise, a specific name must be provided using
|
/// if it is compatible. Otherwise, a specific name must be provided using
|
||||||
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
||||||
pub fn from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
templ: &crate::PadTemplate,
|
templ: &crate::PadTemplate,
|
||||||
|
@ -206,6 +225,9 @@ impl GhostPad {
|
||||||
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
||||||
/// if it is compatible. Otherwise, a specific name must be provided using
|
/// if it is compatible. Otherwise, a specific name must be provided using
|
||||||
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
||||||
pub fn builder_from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn builder_from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
templ: &crate::PadTemplate,
|
templ: &crate::PadTemplate,
|
||||||
|
@ -689,6 +711,9 @@ impl<T: IsA<GhostPad> + IsA<Pad>> PadBuilder<T> {
|
||||||
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
||||||
/// if it is compatible. Otherwise, a specific name must be provided using
|
/// if it is compatible. Otherwise, a specific name must be provided using
|
||||||
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
mut self,
|
mut self,
|
||||||
target: &P,
|
target: &P,
|
||||||
|
@ -696,92 +721,8 @@ impl<T: IsA<GhostPad> + IsA<Pad>> PadBuilder<T> {
|
||||||
assert_eq!(self.pad.direction(), target.direction());
|
assert_eq!(self.pad.direction(), target.direction());
|
||||||
|
|
||||||
self.pad.set_target(Some(target))?;
|
self.pad.set_target(Some(target))?;
|
||||||
|
self.name =
|
||||||
if self.needs_specific_name {
|
crate::pad::PadBuilderName::CandidateForWildcardTemplate(target.name().to_string());
|
||||||
let mut can_assign_target_name = true;
|
|
||||||
|
|
||||||
if let Some(pad_template) = self.pad.pad_template() {
|
|
||||||
if pad_template.presence() == crate::PadPresence::Request {
|
|
||||||
// Check if the target name is compatible with the name template.
|
|
||||||
use crate::CAT_RUST;
|
|
||||||
|
|
||||||
let target_name = target.name();
|
|
||||||
let mut target_parts = target_name.split('_');
|
|
||||||
for template_part in pad_template.name_template().split('_') {
|
|
||||||
let Some(target_part) = target_parts.next() else {
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': not enough parts compared to template '{}'",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(conv_spec_start) = template_part.find('%') {
|
|
||||||
if conv_spec_start > 0
|
|
||||||
&& !target_part.starts_with(&template_part[..conv_spec_start])
|
|
||||||
{
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': mismatch template '{}' prefix",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let conv_spec_pos = conv_spec_start + 1;
|
|
||||||
match template_part.get(conv_spec_pos..=conv_spec_pos) {
|
|
||||||
Some("s") => {
|
|
||||||
// *There can be only one* %s
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Some("u") => {
|
|
||||||
if target_part
|
|
||||||
.get(conv_spec_start..)
|
|
||||||
.map_or(true, |s| s.parse::<u32>().is_err())
|
|
||||||
{
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': can't parse '%u' from '{target_part}' (template '{}')",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some("d") => {
|
|
||||||
if target_part
|
|
||||||
.get(conv_spec_start..)
|
|
||||||
.map_or(true, |s| s.parse::<i32>().is_err())
|
|
||||||
{
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': can't parse '%i' from '{target_part}' (template '{}')",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
other => unreachable!("Unexpected conversion specifier {other:?}"),
|
|
||||||
}
|
|
||||||
} else if target_part != template_part {
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if can_assign_target_name {
|
|
||||||
self.pad.set_property("name", target.name());
|
|
||||||
self.needs_specific_name = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
@ -911,6 +852,13 @@ mod tests {
|
||||||
.name("ghost_test")
|
.name("ghost_test")
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(ghost_pad.name(), "ghost_test");
|
assert_eq!(ghost_pad.name(), "ghost_test");
|
||||||
|
|
||||||
|
let target = crate::Pad::from_template(&templ);
|
||||||
|
let ghost_pad = GhostPad::builder_with_target(&target)
|
||||||
|
.unwrap()
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(ghost_pad.name().starts_with("ghostpad"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -952,6 +900,13 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(ghost_pad.name(), "my-sink");
|
assert_eq!(ghost_pad.name(), "my-sink");
|
||||||
|
|
||||||
|
let target = crate::Pad::from_template(&sink_templ);
|
||||||
|
let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
|
||||||
|
.unwrap()
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(ghost_pad.name().starts_with("ghostpad"));
|
||||||
|
|
||||||
// # Request template %u
|
// # Request template %u
|
||||||
let wildcard_u_templ = crate::PadTemplate::new(
|
let wildcard_u_templ = crate::PadTemplate::new(
|
||||||
"sink_%u",
|
"sink_%u",
|
||||||
|
@ -983,6 +938,13 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(ghost_pad.name(), "sink_0");
|
assert_eq!(ghost_pad.name(), "sink_0");
|
||||||
|
|
||||||
|
let target = crate::Pad::from_template(&sink_0_templ);
|
||||||
|
let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
|
||||||
|
.unwrap()
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(ghost_pad.name().starts_with("ghostpad"));
|
||||||
|
|
||||||
// # Request template %d_%u
|
// # Request template %d_%u
|
||||||
let wildcard_u_templ = crate::PadTemplate::new(
|
let wildcard_u_templ = crate::PadTemplate::new(
|
||||||
"sink_%d_%u",
|
"sink_%d_%u",
|
||||||
|
|
|
@ -1428,7 +1428,7 @@ impl Pad {
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a new [`Pad`] with the specified [`PadDirection`](crate::PadDirection).
|
/// Creates a new [`Pad`] with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
///
|
||||||
/// An automatically generated name will be assigned.
|
/// The [`Pad`] will be assigned the usual `gst::Object` generated unique name.
|
||||||
///
|
///
|
||||||
/// Use [`Pad::builder()`] to get a [`PadBuilder`] and define options.
|
/// Use [`Pad::builder()`] to get a [`PadBuilder`] and define options.
|
||||||
#[doc(alias = "gst_pad_new")]
|
#[doc(alias = "gst_pad_new")]
|
||||||
|
@ -1439,8 +1439,6 @@ impl Pad {
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a [`PadBuilder`] with the specified [`PadDirection`](crate::PadDirection).
|
/// Creates a [`PadBuilder`] with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
|
||||||
/// An automatically generated name will be assigned.
|
|
||||||
#[doc(alias = "gst_pad_new")]
|
#[doc(alias = "gst_pad_new")]
|
||||||
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1454,11 +1452,14 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`Pad::builder_from_static_template()`] to get a [`PadBuilder`] and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`Pad::builder_from_static_template()`] to get a [`PadBuilder`] and define options.
|
|
||||||
#[doc(alias = "gst_pad_new_from_static_template")]
|
#[doc(alias = "gst_pad_new_from_static_template")]
|
||||||
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1472,7 +1473,8 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_pad_new_from_static_template")]
|
#[doc(alias = "gst_pad_new_from_static_template")]
|
||||||
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1486,11 +1488,11 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`Pad::builder_from_template()`] to get a [`PadBuilder`] and define options.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`Pad::builder_from_template()`] to get a [`PadBuilder`] and define options.
|
|
||||||
#[doc(alias = "gst_pad_new_from_template")]
|
#[doc(alias = "gst_pad_new_from_template")]
|
||||||
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1504,7 +1506,8 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_pad_new_from_template")]
|
#[doc(alias = "gst_pad_new_from_template")]
|
||||||
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1558,18 +1561,22 @@ impl Pad {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) enum PadBuilderName {
|
||||||
|
Undefined,
|
||||||
|
KeepGenerated,
|
||||||
|
UserDefined(String),
|
||||||
|
CandidateForWildcardTemplate(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use = "The builder must be built to be used"]
|
#[must_use = "The builder must be built to be used"]
|
||||||
pub struct PadBuilder<T> {
|
pub struct PadBuilder<T> {
|
||||||
pub(crate) pad: T,
|
pub(crate) pad: T,
|
||||||
pub(crate) needs_specific_name: bool,
|
pub(crate) name: PadBuilderName,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a `PadBuilder` with the specified [`PadDirection`](crate::PadDirection).
|
/// Creates a `PadBuilder` with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
|
||||||
/// An automatically generated name will be assigned. Use [`PadBuilder::name`] or
|
|
||||||
/// [`PadBuilder::maybe_name`] to define a specific name.
|
|
||||||
pub fn new(direction: crate::PadDirection) -> Self {
|
pub fn new(direction: crate::PadDirection) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
@ -1588,7 +1595,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
|
|
||||||
PadBuilder {
|
PadBuilder {
|
||||||
pad,
|
pad,
|
||||||
needs_specific_name: false,
|
name: PadBuilderName::Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1599,7 +1606,8 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
|
||||||
|
@ -1614,7 +1622,8 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
@ -1654,25 +1663,23 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let needs_specific_name = if templ.name().find('%').is_some() {
|
|
||||||
// Pad needs a specific name
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
pad.set_property("name", templ.name());
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
PadBuilder {
|
PadBuilder {
|
||||||
pad,
|
pad,
|
||||||
needs_specific_name,
|
name: PadBuilderName::Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Uses the `gst::Object` generated unique name.
|
||||||
|
pub fn generated_name(mut self) -> Self {
|
||||||
|
self.name = PadBuilderName::KeepGenerated;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Sets the name of the Pad.
|
/// Sets the name of the Pad.
|
||||||
pub fn name(mut self, name: impl glib::IntoGStr) -> Self {
|
pub fn name(mut self, name: impl Into<String>) -> Self {
|
||||||
name.run_with_gstr(|name| self.pad.set_property("name", name));
|
self.name = PadBuilderName::UserDefined(name.into());
|
||||||
self.needs_specific_name = false;
|
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1682,7 +1689,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
///
|
///
|
||||||
/// This method is convenient when the `name` is provided as an `Option`.
|
/// This method is convenient when the `name` is provided as an `Option`.
|
||||||
/// If the `name` is `None`, this has no effect.
|
/// If the `name` is `None`, this has no effect.
|
||||||
pub fn maybe_name<N: glib::IntoGStr>(self, name: Option<N>) -> Self {
|
pub fn maybe_name<N: Into<String>>(self, name: Option<N>) -> Self {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
self.name(name)
|
self.name(name)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1695,7 +1702,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
///
|
///
|
||||||
/// This method is convenient when the `name` is provided as an `Option`.
|
/// This method is convenient when the `name` is provided as an `Option`.
|
||||||
/// If the `name` is `None`, this has no effect.
|
/// If the `name` is `None`, this has no effect.
|
||||||
pub fn name_if_some<N: glib::IntoGStr>(self, name: Option<N>) -> Self {
|
pub fn name_if_some<N: Into<String>>(self, name: Option<N>) -> Self {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
self.name(name)
|
self.name(name)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2047,18 +2054,132 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
/// and no specific `name` was provided using [`PadBuilder::name`]
|
/// and no specific `name` was provided using [`PadBuilder::name`]
|
||||||
/// or [`PadBuilder::maybe_name`], or for [`GhostPad`s](crate::GhostPad),
|
/// or [`PadBuilder::maybe_name`], or for [`GhostPad`s](crate::GhostPad),
|
||||||
/// by defining a `target`.
|
/// by defining a `target`.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[must_use = "Building the pad without using it has no effect"]
|
#[must_use = "Building the pad without using it has no effect"]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn build(self) -> T {
|
pub fn build(self) -> T {
|
||||||
if self.needs_specific_name {
|
let Self { pad, name } = self;
|
||||||
panic!(concat!(
|
|
||||||
"Attempt to build a Pad from a wildcard-name template",
|
let templ = pad.pad_template();
|
||||||
" or with a target Pad with an incompatible name.",
|
|
||||||
" Make sure to define a specific name using PadBuilder.",
|
use PadBuilderName::*;
|
||||||
));
|
match (name, templ) {
|
||||||
|
(KeepGenerated, _) => (),
|
||||||
|
(Undefined, None) => (),
|
||||||
|
(Undefined, Some(templ)) => {
|
||||||
|
if templ.name().find('%').is_some() {
|
||||||
|
panic!(concat!(
|
||||||
|
"Attempt to build a Pad from a wildcard-name template",
|
||||||
|
" or with a target Pad with an incompatible name.",
|
||||||
|
" Make sure to define a specific name using PadBuilder",
|
||||||
|
" or opt-in to keep the automatically generated name.",
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
pad.set_property("name", templ.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(UserDefined(name), _) | (CandidateForWildcardTemplate(name), None) => {
|
||||||
|
pad.set_property("name", name);
|
||||||
|
}
|
||||||
|
(CandidateForWildcardTemplate(name), Some(templ)) => {
|
||||||
|
if templ.name().find('%').is_none() {
|
||||||
|
// Not a widlcard template
|
||||||
|
pad.set_property("name", templ.name());
|
||||||
|
} else {
|
||||||
|
let mut can_assign_name = true;
|
||||||
|
|
||||||
|
if templ.presence() == crate::PadPresence::Request {
|
||||||
|
// Check if the name is compatible with the name template.
|
||||||
|
use crate::CAT_RUST;
|
||||||
|
|
||||||
|
let mut name_parts = name.split('_');
|
||||||
|
for templ_part in templ.name_template().split('_') {
|
||||||
|
let Some(name_part) = name_parts.next() else {
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using Pad name '{name}': not enough parts compared to template '{}'",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(conv_spec_start) = templ_part.find('%') {
|
||||||
|
if conv_spec_start > 0
|
||||||
|
&& !name_part.starts_with(&templ_part[..conv_spec_start])
|
||||||
|
{
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using Pad name '{name}': mismatch template '{}' prefix",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let conv_spec_pos = conv_spec_start + 1;
|
||||||
|
match templ_part.get(conv_spec_pos..=conv_spec_pos) {
|
||||||
|
Some("s") => {
|
||||||
|
// *There can be only one* %s
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Some("u") => {
|
||||||
|
if name_part
|
||||||
|
.get(conv_spec_start..)
|
||||||
|
.map_or(true, |s| s.parse::<u32>().is_err())
|
||||||
|
{
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using Pad name '{name}': can't parse '%u' from '{name_part}' (template '{}')",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some("d") => {
|
||||||
|
if name_part
|
||||||
|
.get(conv_spec_start..)
|
||||||
|
.map_or(true, |s| s.parse::<i32>().is_err())
|
||||||
|
{
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using target Pad name '{name}': can't parse '%i' from '{name_part}' (template '{}')",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
unreachable!("Unexpected conversion specifier {other:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if name_part != templ_part {
|
||||||
|
can_assign_name = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if can_assign_name {
|
||||||
|
pad.set_property("name", name);
|
||||||
|
} else {
|
||||||
|
panic!(concat!(
|
||||||
|
"Attempt to build a Pad from a wildcard-name template",
|
||||||
|
" with a target Pad with an incompatible name.",
|
||||||
|
" Make sure to define a specific name using PadBuilder",
|
||||||
|
" or opt-in to keep the automatically generated name.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pad
|
pad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2484,11 +2605,21 @@ mod tests {
|
||||||
let pad = crate::Pad::builder(crate::PadDirection::Unknown).build();
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown).build();
|
||||||
assert!(pad.name().starts_with("pad"));
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
.maybe_name(None::<&str>)
|
.maybe_name(None::<&str>)
|
||||||
.build();
|
.build();
|
||||||
assert!(pad.name().starts_with("pad"));
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
|
.name_if_some(None::<&str>)
|
||||||
|
.build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
let pad = crate::Pad::builder(crate::PadDirection::Sink)
|
let pad = crate::Pad::builder(crate::PadDirection::Sink)
|
||||||
.name("sink_0")
|
.name("sink_0")
|
||||||
.build();
|
.build();
|
||||||
|
@ -2509,6 +2640,11 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(pad.name(), "test");
|
assert_eq!(pad.name(), "test");
|
||||||
|
|
||||||
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
|
.name_if_some(Some("test"))
|
||||||
|
.build();
|
||||||
|
assert_eq!(pad.name(), "test");
|
||||||
|
|
||||||
let caps = crate::Caps::new_any();
|
let caps = crate::Caps::new_any();
|
||||||
let templ = crate::PadTemplate::new(
|
let templ = crate::PadTemplate::new(
|
||||||
"sink",
|
"sink",
|
||||||
|
@ -2526,6 +2662,9 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert!(pad.name().starts_with("audio_sink"));
|
assert!(pad.name().starts_with("audio_sink"));
|
||||||
|
|
||||||
|
let pad = Pad::builder_from_template(&templ).generated_name().build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
let templ = crate::PadTemplate::new(
|
let templ = crate::PadTemplate::new(
|
||||||
"audio_%u",
|
"audio_%u",
|
||||||
crate::PadDirection::Sink,
|
crate::PadDirection::Sink,
|
||||||
|
@ -2536,6 +2675,9 @@ mod tests {
|
||||||
|
|
||||||
let pad = Pad::builder_from_template(&templ).name("audio_0").build();
|
let pad = Pad::builder_from_template(&templ).name("audio_0").build();
|
||||||
assert!(pad.name().starts_with("audio_0"));
|
assert!(pad.name().starts_with("audio_0"));
|
||||||
|
|
||||||
|
let pad = Pad::builder_from_template(&templ).generated_name().build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue