Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate convert for closed intervals in favor of only #145

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ Open
Unbounded
first
last
only
span
isclosed
isopen
Expand Down
30 changes: 18 additions & 12 deletions src/anchoredinterval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,23 +176,29 @@ span(interval::AnchoredInterval{P}) where P = abs(P)

##### CONVERSION #####

# Allows an interval to be converted to a scalar when the set contained by the interval only
# contains a single element.
function Base.only(interval::AnchoredInterval{P}) where {P}
pabloferz marked this conversation as resolved.
Show resolved Hide resolved
if isclosed(interval) && (sign(P) == 0 || first(interval) == last(interval))
return first(interval)
else
throw(DomainError(interval,
"The interval is not closed with coinciding endpoints, " *
"did you meant to use `anchor(interval)`?"
))
end
end

# Remove in version 2.0.0
function Base.convert(::Type{T}, interval::AnchoredInterval{P,T}) where {P,T}
depwarn(
"`convert(::Type{T}, interval::AnchoredInterval{P, T})` is deprecated, " *
"use `only(interval::AnchoredInterval{P,T})` for closed intervals with " *
"coinciding endpoints or `anchor(interval)` otherwise.",
:convert,
)
if isclosed(interval) && (sign(P) == 0 || first(interval) == last(interval))
return first(interval)
else
# Remove deprecation in version 2.0.0
depwarn(
"`convert(T, interval::AnchoredInterval{P,T})` is deprecated for " *
"intervals which are not closed with coinciding endpoints. " *
"Use `anchor(interval)` instead.",
:convert,
)
return anchor(interval)

# TODO: For when deprecation is removed
# throw(DomainError(interval, "The interval is not closed with coinciding endpoints"))
end
end

Expand Down
22 changes: 17 additions & 5 deletions src/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,20 +233,32 @@ function Base.maximum(interval::AbstractInterval{T,L,Open}; increment=nothing) w
throw(BoundsError(interval, next_val))
end

##### CONVERSION #####
"""
only(interval::AbstractInterval)

# Allows an interval to be converted to a scalar when the set contained by the interval only
# contains a single element.
function Base.convert(::Type{T}, interval::Interval{T}) where T
Returns the only element of a closed interval with coinciding endpoints (throws a
DomainError otherwise).
pabloferz marked this conversation as resolved.
Show resolved Hide resolved
"""
function Base.only(interval::Interval)
pabloferz marked this conversation as resolved.
Show resolved Hide resolved
pabloferz marked this conversation as resolved.
Show resolved Hide resolved
if first(interval) == last(interval) && isclosed(interval)
return first(interval)
else
throw(DomainError(interval, "The interval is not closed with coinciding endpoints"))
end
end

##### DISPLAY #####
##### CONVERSION #####

function Base.convert(::Type{T}, interval::Interval{T}) where {T}
depwarn(
"`convert(::Type{T}, interval::Interval{T})` is deprecated, " *
"use `only(interval)` instead.",
:convert,
)
return only(interval)
end
pabloferz marked this conversation as resolved.
Show resolved Hide resolved

##### DISPLAY #####

function Base.show(io::IO, interval::Interval{T,L,R}) where {T,L,R}
if get(io, :compact, false)
Expand Down
9 changes: 4 additions & 5 deletions test/anchoredinterval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,16 @@ using Intervals: Bounded, Ending, Beginning, canonicalize, isunbounded

@testset "conversion" begin
interval = AnchoredInterval{Hour(0)}(dt)
@test convert(DateTime, interval) == dt
@test only(interval) == dt

he = HourEnding(dt)
hb = HourBeginning(dt)

# Note: When the deprecation is dropped remove the deprecated tests and uncomment
# the DomainError tests
@test_throws DomainError only(he)
@test_throws DomainError only(hb)

@test (@test_deprecated convert(DateTime, he)) == anchor(he)
@test (@test_deprecated convert(DateTime, hb)) == anchor(hb)
# @test_throws DomainError convert(DateTime, he)
# @test_throws DomainError convert(DateTime, hb)

@test convert(Interval, he) == Interval{Open, Closed}(dt - Hour(1), dt)
@test convert(Interval, hb) == Interval{Closed, Open}(dt, dt + Hour(1))
Expand Down
23 changes: 13 additions & 10 deletions test/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,22 @@
end

@testset "conversion" begin
pabloferz marked this conversation as resolved.
Show resolved Hide resolved
@test_throws DomainError convert(Int, Interval{Open, Open}(10, 10))
@test_throws DomainError convert(Int, Interval{Open, Closed}(10, 10))
@test_throws DomainError convert(Int, Interval{Closed, Open}(10, 10))
@test convert(Int, Interval{Closed, Closed}(10, 10)) == 10
@test_throws DomainError convert(Int, Interval{Closed, Closed}(10, 11))
@test_throws DomainError only(Interval{Open, Open}(10, 10))
@test_throws DomainError only(Interval{Open, Closed}(10, 10))
@test_throws DomainError only(Interval{Closed, Open}(10, 10))
@test only(Interval{Closed, Closed}(10, 10)) == 10
@test_throws DomainError only(Interval{Closed, Closed}(10, 11))

@test (@test_deprecated convert(Int, Interval{Closed, Closed}(10, 10))) == 10
@test_deprecated (@test_throws DomainError convert(Int, Interval{Closed, Closed}(10, 11)))

for T in (Date, DateTime)
dt = T(2013, 2, 13)
@test_throws DomainError convert(T, Interval{Open, Open}(dt, dt))
@test_throws DomainError convert(T, Interval{Open, Closed}(dt, dt))
@test_throws DomainError convert(T, Interval{Closed, Open}(dt, dt))
@test convert(T, Interval{Closed, Closed}(dt, dt)) == dt
@test_throws DomainError convert(T, Interval{Closed, Closed}(dt, dt + Day(1)))
@test_throws DomainError only(Interval{Open, Open}(dt, dt))
@test_throws DomainError only(Interval{Open, Closed}(dt, dt))
@test_throws DomainError only(Interval{Closed, Open}(dt, dt))
@test only(Interval{Closed, Closed}(dt, dt)) == dt
@test_throws DomainError only(Interval{Closed, Closed}(dt, dt + Day(1)))
end
end

Expand Down