Skip to content

Conversation

dfed
Copy link
Owner

@dfed dfed commented Jun 27, 2025

It can be really useful to share an @Instantiable across boundaries where only some of their properties exist

@dfed dfed self-assigned this Jun 27, 2025
@dfed dfed force-pushed the dfed--only-if-available branch 2 times, most recently from 136f45e to 09cf720 Compare June 27, 2025 02:54
@dfed dfed force-pushed the dfed--only-if-available branch from 09cf720 to 0e81531 Compare June 27, 2025 03:04
Copy link

codecov bot commented Jun 27, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.92%. Comparing base (116a878) to head (40b5156).
Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##             main     #168    +/-   ##
========================================
  Coverage   99.92%   99.92%            
========================================
  Files          32       32            
  Lines        3757     3942   +185     
========================================
+ Hits         3754     3939   +185     
  Misses          3        3            
Files with missing lines Coverage Δ
...ces/SafeDICore/Errors/FixableInjectableError.swift 100.00% <100.00%> (ø)
...eDICore/Extensions/AttributeSyntaxExtensions.swift 100.00% <100.00%> (ø)
...afeDICore/Generators/DependencyTreeGenerator.swift 100.00% <100.00%> (ø)
Sources/SafeDICore/Generators/ScopeGenerator.swift 100.00% <100.00%> (ø)
Sources/SafeDICore/Models/Dependency.swift 100.00% <100.00%> (ø)
Sources/SafeDICore/Models/Initializer.swift 100.00% <100.00%> (ø)
Sources/SafeDICore/Models/Property.swift 100.00% <100.00%> (ø)
Sources/SafeDICore/Models/Scope.swift 100.00% <100.00%> (ø)
Sources/SafeDICore/Models/TypeDescription.swift 99.60% <100.00%> (+0.01%) ⬆️
...rces/SafeDICore/Visitors/InstantiableVisitor.swift 100.00% <100.00%> (ø)
... and 2 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dfed dfed force-pushed the dfed--only-if-available branch from 9da75a3 to 52e815e Compare June 27, 2025 06:48
@@ -2,7 +2,7 @@

set -e

VERSION='1.1.0'
VERSION='1.2.2'
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this version is always behind

@dfed dfed marked this pull request as ready for review June 27, 2025 07:01
Copy link
Collaborator

@ahmdmhasn ahmdmhasn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's great to see how SafeDI evolves over time. One key change is that developers are now responsible for ensuring a dependency’s existence when needed, unlike before when SafeDI guaranteed its availability.

@attached(peer)
public macro Received() = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro")
public macro Received(onlyIfAvailable: Bool = false) = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public macro Received(onlyIfAvailable: Bool = false) = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro")
public macro Received(availability: ReceiveMode = .always) = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro")
public enum ReceiveMode {
    /// The parent always provides dependency.
    case always
    /// Dependency is provided only when available.
    case ifAvailable
}

Just a suggestion, but I think using an enum here could make the dependency availability clearer and more extensible compared to a boolean. Let me know what you think!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another idea that I have in mind, if SafeDI can infer if the value is optional, then it's not mandatory to receive this value? Then there's no need to pass an additional value and keep the same Swift fundamental syntax.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the idea of the future proofed enum. Gonna chew on that. Makes it easier to avoid breaking changes which is great. But I'm struggling to think of ways I'd expand this.

Re inferring options, there are two reasons I didn't do this:

  • If someone spells out Optional I don’t know if they’re referring to Swift.Optional or their own type, and I can’t force them to clarify because they haven’t told me that’s what they’re doing – it’s a bit too easy to screw up. You might legitimately be forwarding in an optional and want the safety
  • The parameter makes it very clear when you’re opting out of the safety provided by SafeDI

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of creating a separate macro: @Received and @ReceivedIfAvailable? I'm generally a fan of creating two separate functions, macros, etc instead of creating a single function with a boolean property.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been pretty steadfast in trying to reduce the number of macros that folk need to learn.

By limiting the number of entry points to SafeDI, we:

  • make the basics of SafeDI easier to learn
  • make it easy to discover more advanced functionality, since all advanced functionality is available off of the four macros

There are four core concepts in SafeDI, and each maps 1:1 to a macro. I plan on riding that wave for as long as we can.

return "let \(property.label) = \(property.typeDescription.asSource)(\(fulfillingProperty.label))"
case let .alias(property, fulfillingProperty, erasedToConcreteExistential, onlyIfAvailable):
return if onlyIfAvailable, unavailableProperties.contains(fulfillingProperty) {
"// Did not create `\(property.asSource)` because `\(fulfillingProperty.asSource)` is unavailable."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this, it's the developer's responsibility to ensure this dependency exists when needed.

Copy link
Collaborator

@MrAdamBoyd MrAdamBoyd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit rusty with SafeDI as I haven't used it in a 8 or 9 months, but I can imagine some situations where this would be useful. Nice!

@attached(peer)
public macro Received() = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro")
public macro Received(onlyIfAvailable: Bool = false) = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of creating a separate macro: @Received and @ReceivedIfAvailable? I'm generally a fan of creating two separate functions, macros, etc instead of creating a single function with a boolean property.

@dfed
Copy link
Owner Author

dfed commented Jun 27, 2025

One key change is that developers are now responsible for ensuring a dependency’s existence when needed, unlike before when SafeDI guaranteed its availability

Correct! Though I do want to underline that this is an opt-in feature, so by default you still have compile-time safety guaranteed. Just giving you more adventures to choose from

@dfed dfed merged commit 011fc0f into main Jun 30, 2025
20 checks passed
@dfed dfed deleted the dfed--only-if-available branch June 30, 2025 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants